原型模式

2019-02-21 13:38:13 浏览数 (2)

1.定义

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。被复制的实例就是“原型”,这个原型是可定制的。

2.示例

代码语言:javascript复制
public class WordDocument implements Cloneable {
    private String mText;
    private ArrayList<String> mImages = new ArrayList<String>();

    public WordDocument() {
        super();
        System.out.println("WordDocument");
    }

    public String getText() {
        return mText;
    }

    public void setText(String mText) {
        this.mText = mText;
    }

    public ArrayList<String> getmImages() {
        return mImages;
    }

    public void setImages(ArrayList<String> mImages) {
        this.mImages = mImages;
    }

    public void addImg(String img){
        this.mImages.add(img);
    }

    @Override
    public String toString() {
        return "WordDocument [mText="   mText   ", mImages="   mImages   "]";
    }

    @Override
    protected WordDocument clone() throws CloneNotSupportedException {
        try {
            WordDocument document = (WordDocument) super.clone();
            //document.mImages = (ArrayList<String>) this.mImages.clone();
            //没有这句话表示浅拷贝,也就是C  的引用传递
            return document;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

测试代码:

代码语言:javascript复制
    public static void main(String[] args) throws CloneNotSupportedException {
        WordDocument doc = new WordDocument();
        doc.setText("origin");
        doc.addImg("img ori");
        System.out.println(doc);

        System.out.println("--------------------clone-------------------------");
        WordDocument doc2 = doc.clone();
        System.out.println(doc2);

        doc2.setText("modify");
        doc2.addImg("img  2");
        System.out.println(doc2);

        System.out.println(doc);
    }

实例中如果有注释,也就是浅拷贝,那么打印情况如下

代码语言:javascript复制
WordDocument
WordDocument [mText=origin, mImages=[img ori]]
--------------------clone-------------------------
WordDocument [mText=origin, mImages=[img ori]]
WordDocument [mText=modify, mImages=[img ori, img  2]]
WordDocument [mText=origin, mImages=[img ori, img  2]]//****引用传递传的是地址,所以把对应地址保存的数据改了,那么原数据也改了

如果改成深拷贝

代码语言:javascript复制
WordDocument
WordDocument [mText=origin, mImages=[img ori]]
--------------------clone-------------------------
WordDocument [mText=origin, mImages=[img ori]]
WordDocument [mText=modify, mImages=[img ori, img  2]]
WordDocument [mText=origin, mImages=[img ori]]//原数据没变

3.总结

优点 (1)原型模式是在内存中二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量对象时,原型模式可能更好的体现其优点。 (2)还有一个重要的用途就是保护性拷贝,也就是对某个对象对外可能是只读的,为了防止外部对这个只读对象的修改,通常可以通过返回一个对象拷贝的形式实现只读的限制。 缺点: (1)这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的,在实际开发中应该注意这个潜在问题。优点是减少了约束,缺点也是减少了约束,需要大家在实际应用时考虑。 (2)通过实现Cloneable接口的原型模式在调用clone函数构造实例时并不一定比通过new操作速度快,只有当通过new构造对象较为耗时或者说成本较高时,通过clone方法才能够获得效率上的提升。

参考:http://blog.csdn.net/qq_17766199/article/details/50265009

0 人点赞