原型模式

1.原型模式简介

说白了原型模式(Prototype Pattern)就是使用一个存在的对象高效地创建多个重复的对象。属于创建型模式。做法是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。

关键代码:实现克隆操作,继承 Cloneable接口,重写clone()方法。
应用实例:细胞分裂、java中的Object clone()方法。
优点:性能提高、逃避构造函数的约束(注意使用clone()方法创建的对象不会调用构造方法)
使用场景:
a.资源优化场景。
b.类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
c.性能和安全要求的场景。
d.通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
e.一个对象多个修改者又不想互相产生影响的场景。
f.一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
g.在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与 Java 融为浑然一体,大家可以随手拿来使用。

注意事项:与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。

 

2.Demo

import java.util.Hashtable; //注意table的t是小写的!

abstract class Shape implements Cloneable { //使用clone第一步:实现Cloneable接口
    private String id;
    protected String type;

    public Shape() {
        System.out.println("Shape()");
    }

    public String getType() {
        return this.type;
    }

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    /*public也是可以的,扩大权限可以,缩小权限不行*/
    protected Object clone() throws CloneNotSupportedException { //使用clone第二步:复写clone()方法
        return super.clone();
    }
}

class Rectangle extends Shape {
    public Rectangle() {
        this.type = "Rectangle";
        System.out.println("Rectangle");
    }

    public void printInfo() {
        System.out.println("Rectangle: printInfo()");
    }
}

class Square extends Shape {
    public Square() {
        this.type = "Square";
        System.out.println("Square");
    }

    public void printInfo() {
        System.out.println("Square: printInfo()");
    }
}

class ShapeCache {
    private static Hashtable<String, Shape> table = new Hashtable<String, Shape>();
    
    public static void shapeCache() {
        Rectangle rect = new Rectangle();
        rect.setId("Rectangle");
        table.put(rect.getId(), rect);

        Square squ = new Square();
        squ.setId("Square");
        table.put(squ.getId(), squ);
    }

    public static Shape getShape(String id) { //提供一个获取新实例的方法
        Shape shape = table.get(id); //提供一个找出正确实例原型的方法
        try {
            return (Shape)shape.clone(); //委托复制实例的方法生成新实例
        } catch (Exception e) { //CloneNotSupportedException e 和 Exception e 都是可以的,后者应该是前者的父类
            return null;
        }
    }
}


public class PrototypePatternDemo {
    public static void main(String args[]) {
        ShapeCache.shapeCache();

        /*可以使用那一个原型克隆出一组对象*/
        Shape rect1 = ShapeCache.getShape("Rectangle"); 
        Shape rect2 = ShapeCache.getShape("Rectangle");
        Shape rect3 = ShapeCache.getShape("Rectangle");
        System.out.println(rect1);
        System.out.println(rect2);
        System.out.println(rect3);

        Shape squ1 = ShapeCache.getShape("Square");
        Shape squ2 = ShapeCache.getShape("Square");
        Shape squ3 = ShapeCache.getShape("Square");
        System.out.println(squ1);
        System.out.println(squ2);
        System.out.println(squ3);
    }
}


/*
$ java PrototypePatternDemo 
Shape()            //注意构造方法只调用了2次!
Rectangle
Shape()
Square
Rectangle@40c84051
Rectangle@1af6a711
Rectangle@37525aeb
Square@7fcf16ac
Square@74d9b7c1
Square@1af1bd6
*/

 

 

 

 

 

 

参考:http://www.runoob.com/design-pattern/prototype-pattern.html

 

posted on 2019-04-14 12:19  Hello-World3  阅读(154)  评论(0编辑  收藏  举报

导航