原型模式

1.原型模式的介绍

  原型模式是一个创建型的模式,该模式应该有一个样板实例,用户从这个样板对象中复制出一个内部属性

  一致的对象,这个过程俗称克隆,被复制的实例就是所称的原型,原型可定制。原型模式多用于创建复杂

  的或者构造耗时的实例,因为这种情况下,复制一个已经存在的实例可使程序运行更高效。

2.定义

  用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象。

3.使用场景:

  1>.类的初始化需要消耗非常多的资源,这个资源包括数据,硬件资源等。原型复制可以避免这些消耗。

  2>.通过new产生一个对象需要非常繁琐的数据准备或访问权限,这时可以使用原型复制。

  3>.一个对象需要提供给其它对象访问,而且各个调用者可能都需要修改其值时,可以考虑用原型模式复

  制多个对象供调用者使用,即保护性拷贝。

  注意:通过实现Cloneable接口的原型模式在调用clone函数构造实例时并不一定比通过new操作速度快,

  只有当通过new构造对象较为耗时或者说成本较高时,通过clone方法才能够获得效率上的提升。因此,

  在使用Cloneable时需要考虑构建对象的成本以及做一些效率上的测试。当然原型模式也不一定非要实现

  Cloneable接口,也有其它的实现方式。

4.总结

  原型模式本质上就是对象拷贝,与C++中拷贝构造函数有些类似,它们之间容易出现的问题也都是深拷贝

  ,浅拷贝。使用原型模式可以解决构建复杂对象的资源消耗问题,能够在某些场景下提升创建对象的效率

  。还有一个重要的用途就是保护性拷贝,也就是某个对象对外可能是只读的,为了防止外部对这个只读对

  象修改,通常可以通过返回一个对象拷贝的形式实现只读的限制。

  优点:原型模式是在内存中二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体

  内产生大量的对象时,原型模式可以更好地体现其优点。

  缺点:即是优点也是缺点,直接在内存中拷贝,构造函数是不会执行的,在实际开发当中应该注意这个潜

  在的问题。优点就是减少了约束,缺点也是减少了约束。

5.简单实例

public class WrodDocument implements Cloneable {
    private String mText;
    private ArrayList<String> mImages = new ArrayList<>();

    public WrodDocument() {
        System.out.println("------------------WordDocument构造函数----------------");
    }

    @Override
    protected WrodDocument clone() {
        try {
            WrodDocument doc = null;
            doc = (WrodDocument) super.clone();
            doc.mText = this.mText;
            doc.mImages = (ArrayList<String>) this.mImages.clone();
            return doc;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getmText() {
        return mText;
    }

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

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

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

    public void showDocument(){
        System.out.println("---------------Word Content Start---------------");
        System.out.println("Text:"+mText);
        System.out.println("Images List:");
        for (String imgName:mImages){
            System.out.println("image name:"+imgName);
        }
        System.out.println("---------------Word Content End------------------");
    }
}
public class Client {
    public static void main(String[] args) {
        WrodDocument originDoc=new WrodDocument();
        originDoc.setmText("这是一篇文档");
        originDoc.addImages("图片1");
        originDoc.addImages("图片2");
        originDoc.addImages("图片3");
        originDoc.showDocument();
        WrodDocument doc2=originDoc.clone();
        doc2.showDocument();
        doc2.setmText("这是修改过的Doc2文本");
        originDoc.setmText("测试修改");
        originDoc.addImages("测试");
        doc2.showDocument();
        originDoc.showDocument();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章