设计模式-原型模式

原型模式也可以称为克隆模式,是指用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

克隆模式的主要应用场景有两种

1.用new创建对象代价较大,如一个对象设置了非常多的属性,有非常复杂的创建过程,则不适合用new操作将所有属性和操作重复一遍。或者创建一个对象对资源开销非常大,也不适合直接用new

2.保护性拷贝,多个操作修改类对象的属性值时,为了保证数据准确性可以克隆多个对象供相应的操作调用。

实现方式:

一、浅拷贝(影子拷贝)

java中提供了Cloneable接口,需要拷贝的类只需要实现这个接口,重写里面的方法。

package com.example.clonemodel;


import java.util.ArrayList;

public class WordDocument implements Cloneable {

    private String mText;

    private ArrayList<String> mImages = new ArrayList<>();

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

    @Override
    protected WordDocument clone() throws CloneNotSupportedException {

        WordDocument wordDocument = (WordDocument) super.clone();

        wordDocument.mText = this.mText;
        wordDocument.mImages = this.mImages;
        return wordDocument;
    }

    public void showDocument(){
        System.out.println("-------------Word content start ----------------");
        System.out.println("Text : " + mText);
        System.out.println("ImageList : " );
        for (String imgName : mImages) {
            System.out.println("image name :"+imgName);
        }
        System.out.println("-------------Word content end -------------------");
    }

    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 image){
        this.mImages.add(image);
    }
}
package com.example.clonemodel;

public class Client {
    public static void main(String[] args) {
        WordDocument wordDocument = new WordDocument();
        wordDocument.setmText("This is a word");
        wordDocument.addImage("iamge 1");
        wordDocument.addImage("iamge 2");
        wordDocument.addImage("iamge 3");
        wordDocument.addImage("iamge 4");
        //输出原始文档
        wordDocument.showDocument();

        WordDocument document = null;
        try {
            document = wordDocument.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        //输入克隆文档
        document.showDocument();

        //修改新文档后输出原始文档 ,原始文档内容不受影响
        document.setmText("This is a song");
        document.showDocument();
        wordDocument.showDocument();


    }
}

 

上述demo中WordDocunment中对象被克隆修改,克隆出的对象属性和原始对象一致,修改克隆出的对象属性,不会影响原对象。因为可以看出克隆模式是重新创建一个对象,而不是将对象指给另一个引用而已。

二、深拷贝

上述只是浅拷贝,为什么是浅拷贝,细心的读者可能已经发现,在demo中重写的clone方法中有这么一句

wordDocument.mImages = this.mImages;

克隆对象的图片列表是直接指向原对象的列表对象,所以这个属性本质上是一个对象,只不过对象的引用不一样而已。因此可以预见在修改拷贝对象的图片列表属性时,原对象的图片列表属性也会变化。这里就不再贴代码了,只需将上述demo简单修改运行即可。

那么如何修改呢,很简单只需要将上边demo中clone方法修改一下

 @Override
    protected WordDocument clone() throws CloneNotSupportedException {

        WordDocument wordDocument = (WordDocument) super.clone();

        wordDocument.mText = this.mText;
        wordDocument.mImages = (ArrayList<String>) this.mImages.clone();
        return wordDocument;
    }

有些读者可能会奇怪为什么一开始的demo中的mText属性,在克隆对象中修改不会影响原对象。这是java中String类的机制,这里不再赘述,有兴趣的读者可以自行学习一下,简单来说String对象是不可修改的,任何对他的修改都是新建操作。

 

 

PS:此demo摘抄自《Android源码设计模式解析与实战》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值