设计模式之原型模式

原型模式:用原型指定创建原型的种类,并且通过拷贝原型创建新的对象。

简单点说:原型模式和工厂模式一样都属于创建型模式,但是工厂模式是根据你的需求创建不同的对象,原型模式是根据原型创建一样的对象(复制拷贝),工厂模式是用new创建对象,原型模式是根据原型克隆创建对象效率更高。

打个比方:流水线上生产华为手机(对象),首先得有一个手机样品模板(即原型),所有的华为手机(对象)都根据这个模板生产。因此一条流水线运行下来,生产的手机都长一样(复制,克隆)。这就是原型模式

为什么要使用原型模式?

原型模式创建对象用的是objec类中clone方法(浅克隆),它操作的是本地方法,效率高,并且new对象不能具备当前运行时的状态,new产生的对象是通过构造方法中的默认值生成;


原型模式通常和工厂模式结合使用:

通常通过原型模式克隆一个对象,然后通过工厂提供给调用者。


原型模式代码示例(浅克隆):

场景:把齐天大圣当作一个对象,然后把齐天大圣的金箍棒也看成一个对象,齐天大圣会持有金箍棒的引用。齐天大圣会变化出千万个自己,这就是一个原型模式,但是发现一个问题,所有齐天大圣持有的金箍棒是同一根,请看下面示例。

1.猴子类:

2.金箍棒类:


3.齐天大圣类:持有金箍棒的引用,并实现cloneable接口


测试:


可以看出clone出来的齐天大圣是不同的对象,但是他们的金箍棒都是同一根。


我们再看一个示例:

原型类:


测试代码:


输出结果:



总结:通过上面代码可以看出,实现Cloneable接口只能实现浅克隆,它能实现基本类型的值进行复制,但是类似集合类型,引用类型它只是复制了对象的引用,指向的还是原有的对象。所有克隆对象中引用类型或集合类型指向的是同一个地址,若对克隆对象属性做修改的时候,可能会影响其它克隆对象,这样是不靠谱的,为了规避这种情况的产生,我们现在来看一下深克隆,它能把对象中的引用也重新克隆。

原型模式深克隆代码示例:

还是引用刚才齐天大圣那个例子,把齐天大圣类的克隆方法重写下:

public class Qitiandasheng extends Monkey implements Serializable,Cloneable {

    //金箍棒
    private JinGuBang jgb=new JinGuBang();

    /**\
     * 序列化实现深度克隆(反射也能实现)
     * 把对象的字节码数组读出来,通过字节码重新构造一个对象
     * @return
     */
    public Object clone() throws CloneNotSupportedException{

        try  {
            ByteArrayOutputStream bos=new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois=new ObjectInputStream(bis);
            Qitiandasheng qtds=(Qitiandasheng)ois.readObject();
            return qtds;

        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    public JinGuBang getJgb() {
        return jgb;
    }

    public void setJgb(JinGuBang jgb) {
        this.jgb = jgb;
    }

    



//    public Object clone() throws CloneNotSupportedException {
//        return super.clone();
//    }

}

测试类:


可以看到两个齐天大圣引用的金箍棒是不相等的。

当然实现深克隆的方式有很多种,我这里用到的是序列化,spring中用到的原型模式大多都是用反射。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值