美文网首页
设计模式---原型(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