设计模式-原型模式

原型模式分析

原型模式(PrototypePattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
.
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

原型模式分为:

  1. 浅克隆
  2. 深克隆

浅克隆

只负责克隆按值传递的数据(比如基本数据类型、String类型),而不复制它所引用的对象,换言之,所有的对其他对象的引用都仍然指向原来的对象。
也就是说如果被克隆的对象中,有对其他对象的引用,那么就只复制那个对象的引用,而不是重新复制一个新的对象。

看下代码示例

public class AdjectiveCopy {

    static class Protro implements Cloneable{
        private String aa = "aaaa";
        private ProtroVar protroVar = new ProtroVar();

        @Override
        protected Protro clone() {
            Protro protro = null;
            try {
                protro = (Protro) super.clone();
            } catch (CloneNotSupportedException e){
                e.printStackTrace();
            }
            return protro;
        }
    }

    static class ProtroVar {
        private String bb = "bbb";
    }

    public static void main(String[] args){
        Protro protro = new Protro();
        Protro clonePro = protro.clone();
        System.out.println("hashCode:  "+(protro.hashCode() == clonePro.hashCode()));
        System.out.println("proVar:  "+(protro.protroVar.hashCode() == clonePro.protroVar.hashCode()));

    }
}

打印结果:

hashCode:  false
proVar:  true

深克隆

除了浅度克隆要克隆的值外,还负责克隆引用类型的数据。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深度克隆把要复制的对象所引用的对象都复制了一遍,而这种对被引用到的对象的复制叫做间接复制。
深克隆的方法有,反序列化,重写Clone()方法等。

public class DeepCopy {

    static class Protro implements Serializable{

        private String aadd = "aadd";
        private ProtroBB protrobb = new ProtroBB();

        public Protro() {
        }

        public Object deepClone() {
            Object o = null;
            try {
                //将对象写到流里
                ByteArrayOutputStream bo = new ByteArrayOutputStream();
                ObjectOutputStream oo = new ObjectOutputStream(bo);
                oo.writeObject(this);
                //从流里读出来
                ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
                ObjectInputStream oi = new ObjectInputStream(bi);
                o = oi.readObject();
            } catch (Exception e) {
                e.printStackTrace();
            }

            return o;
        }
    }

    static class ProtroBB implements Serializable {
        private String cc = "cc";
    }

    public static void main(String[] args){
        Protro protro = new Protro();
        Protro clonePro = (Protro) protro.deepClone();
        System.out.println("hashCode:  "+(protro.hashCode() == clonePro.hashCode()));
        System.out.println("proVar:  "+(protro.protrobb.hashCode() == clonePro.protrobb.hashCode()));

    }
}

打印结果

hashCode:  false
proVar:  false

优点:

  1. 向客户隐藏制造新实例的复杂性。
  2. 提供让客户能够产生未知类型对象的选项。
  3. 在某些环境下,复制对象比创建对象更加有效。

缺点:

  1. 对象的复制有时相当的复杂。特别是当一个类引用不支持序列化的间接对象,或者引用含有循环结构的时候。

用途:

  1. 在一个复杂的类层次中,当系统必须从其中的许多类型创建新对象时,可以考虑原型
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值