美文网首页
设计模式---原型(prototype)

设计模式---原型(prototype)

作者: RalapHao | 来源:发表于2017-09-28 13:55 被阅读0次

    介绍

    是一种创建模式,用户通过一个对象,复制出一个内部属性一致的对象,通俗讲就是克隆,常用在创建复杂或构造耗时的实例中。复制一个已经存在的对象更加高效。

    应用场景

    1. 类的初始化需要消耗大量的资源,可以通过原型拷贝规避;
    2. 通过new产生的对象需要非常繁琐的在准备和权限访问;
    3. 保护拷贝:同一个对象可能需要多个调用者修改其中的属性,原型模式可以拷贝多个副本提供使用;

    UML

    UML.png

    上代码

    1. 浅拷贝
    public class WordDocument implements Cloneable {
    
      private String mText;
      private ArrayList<String> mImages = new ArrayList<>();
    
      public WordDocument() {
          System.out.println("----------------WordDocument构造-----------------");
      }
    
      @Override
      protected Object clone() throws CloneNotSupportedException {
          return super.clone();
      }
    
      public String getmText() {
          return mText;
      }
    
      public void setmText(String mText) {
          this.mText = mText;
      }
    
      public ArrayList<String> getmImages() {
          return mImages;
      }
    
      public void setmImages(ArrayList<String> mImages) {
          this.mImages = mImages;
      }
    
      public void addImage(String imageName) {
          mImages.add(imageName);
      }
    
      @Override
      public String toString() {
          return "WordDocument{" +
                  "mText='" + mText + '\'' +
                  ", mImages=" + mImages +
                  '}';
      }
    
    }
    
    

    测试

     private static WordDocument documentClone;
    
        public static void main(String[] args) {
            WordDocument document = new WordDocument();
            document.setmText("Document");
            document.addImage("image1.jpg");
            document.addImage("image2.jpg");
            document.addImage("image3.jpg");
            System.out.println(document);
            try {
                documentClone = (WordDocument) document.clone();
                System.out.println(documentClone);
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            document.setmText("update");
            document.addImage("image4");
            System.out.println(document.getmImages() == documentClone.getmImages());
            System.out.println(document.getmText() == documentClone.getmText());
            System.out.println();
        }
    

    输出结果

    浅拷贝.png

    注释:

    1. 修改了mText,克隆对象没有变,而ArrayList却是相同的对象,为什么呢?因为Java克隆,基础类型克隆的是值,引用类型克隆的是引用。
      string,integer是线程安全的不可变类,每一次赋值,指向的都是堆上的一个新的对象,所以这里导致了上面的结果。

    为了解决上述问题,原型模式提出了

    1. 深拷贝
      修改clone方法
     @Override
        protected Object clone() throws CloneNotSupportedException {
            WordDocument document = (WordDocument) super.clone();
            document.mText = this.mText;
            document.mImages = (ArrayList<String>) this.mImages.clone();
            return document;
        }
    
    

    输出

    深拷贝.png
    • 深拷贝和浅拷贝的区别就在于clone 方法,

    注意

    1. 通过拷贝的对象不会执行构造函数,
    2. clone是Object的方法并不是Cloneable中的方法,但是想要实现clone必须实现Cloneable,不然会有CloneNotSupportedException异常

    相关文章

      网友评论

          本文标题:设计模式---原型(prototype)

          本文链接:https://www.haomeiwen.com/subject/jmdmextx.html