还为那些设计模式烦恼吗-原型模式

原型模式

原型二字表明了该模式应该有一个样版实例,用户从这个样板对象中复制出一个内部属性一致的对象,被复制的实例就是我们所称的"原型"。
定义:用原型实例指定创建对象的种类,并通过拷贝这此原型创建新的对象(深拷贝和浅拷贝)

浅拷贝

package com.zc.test;

import java.util.ArrayList;

public class DeepCopy implements Cloneable {
    private int num;
    private ArrayList<Integer> mArray = new ArrayList<Integer>();

    @Override
    protected Object clone() throws CloneNotSupportedException {
        try {
            DeepCopy mDeepCopy = (DeepCopy) super.clone();
            mDeepCopy.num = this.num;
            // 这个等于号:一个对象的引用等于别外一个对象,一个对象的改变,别一个对象跟会跟着改变
            //标记1处
            mDeepCopy.mArray = this.mArray;
            return mDeepCopy;
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public int getNum() {
        return num;
    }

    public void addNum(int num) {
        mArray.add(num);
    }

    public void showArray() {
        for (Integer array : mArray) {
            System.out.println(array);
        }
    }

    public void showAllInfo() {
        System.out.println(getNum());
        showArray();
    }
}

调用:

public class Client {

    public static void main(String[] args) throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        
        DeepCopy mDeepCopy1 = new DeepCopy();
        mDeepCopy1.setNum(1);
        mDeepCopy1.addNum(2);
        mDeepCopy1.addNum(3);
        mDeepCopy1.showAllInfo();
        
        DeepCopy mDeepCopy2 = (DeepCopy) mDeepCopy1.clone();
        mDeepCopy2.setNum(2);
        mDeepCopy2.showAllInfo();
        
        mDeepCopy1.showAllInfo();
    }

}

结果:

1
2
3
分隔线
2
2
3
分隔线
1
2
3
分隔线

但是,假如这样调用:

DeepCopy mDeepCopy1 = new DeepCopy();
        mDeepCopy1.setNum(1);
        mDeepCopy1.addNum(2);
        mDeepCopy1.addNum(3);
        mDeepCopy1.showAllInfo();
        
        DeepCopy mDeepCopy2 = (DeepCopy) mDeepCopy1.clone();
        mDeepCopy2.setNum(2);
        mDeepCopy2.showAllInfo();
        
        mDeepCopy1.showAllInfo();

结果:

1
2
3
分隔线
2
2
3
4
分隔线
1
2
3
4
分隔线

上述就是浅拷贝

深拷贝

就是将上面代码的标记1处,改成

mDeepCopy.mArray = (ArrayList<Integer>) this.mArray.clone();

结果就变成了:

1
2
3
分隔线
2
2
3
4
分隔线
1
2
3
分隔线

结论:
1、类初始化需要消化非常多的资源,这个资源包括数据,硬件资源等,通过原型拷贝避免这些消耗。
2、通过new产生一个对象需要非常繁的数据准备或访问权限,这时可以使用原型模式
3、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
注意:通过实现Cloneable接口的原型模式在调用 clone函数构造实例时并不一定比通过new操作速度快,当只有通过new构造对象有时或者成本较高时,通过clone方法才能获取效率上的提升。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容