【设计模式】创建型:原型模式(Prototype Pattern)

什么是原型模式

听说过克隆吧,通俗点说,就是复制,把一个已经存在的对象当作原型,克隆出一个跟它相同的对象,这就是原型模式。

原型对象通常都是经历过初始化操作已经含有一些数据的对象,复制它就是为了省去重新初始化的过程,从而快速得到一个有目标数据的对象。

在面向对象编程领域,克隆又可以细分为两种模式:

  1. 浅克隆:只克隆原型对象自身,原型对象内部持有的其它对象不可隆,但是会保留对象引用。
  2. 深克隆:不仅克隆原型对象自身,还克隆原型对象内部持有的其它对象。

使用时,选择浅克隆还是深克隆,要根据业务场景来判断,千万不能乱用!

原型模式的实现

浅克隆

Java中,顶层对象类java.lang.Object提供有一个clone()方法,就是浅克隆的实现:

/**
 * 必须实现接口:java.lang.Cloneable
 */
public class Prototype implements Cloneable {
    
    public int number = 10;

    public List<String> list = new ArrayList<>();

    /**
     * 重写父类clone()方法,调用super.clone()完成浅克隆
     * 
     * @return 
     */
    @Override
    public Prototype clone() {
        try {
            Prototype clone = (Prototype) super.clone();
            // TODO 克隆对象以后,可以做一些其它的操作
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
     
}

自己动手实现浅克隆:

/**
 * 自己动手,不需要实现接口:java.lang.Cloneable
 */
public class Prototype {
    
    public int number = 10;

    public List<String> list = new ArrayList<>();
    
    /**
     * 因为没有使用父类clone()方法,所以自定义一个其它的方法名,不使用clone
     * 
     * @return 
     */
    public Prototype cloneObject() {
        Prototype clone = new Prototype();
        clone.number = this.number;
        clone.list = this.list;
        return clone;
    }
    
}

上述两种方法都能实现浅克隆操作,克隆对象和原型对象持有的list属性对象都是同一个。

深克隆

Java默认没有提供深克隆的操作接口,可以在浅克隆clone()的基础上加以变通,达到深克隆的效果:

/**
 * 必须实现接口:java.lang.Cloneable
 */
public class Prototype implements Cloneable {
    
    public int number = 10;

    public List<String> list = new ArrayList<>();

    /**
     * 重写父类clone()方法,调用super.clone()完成浅克隆
     * 
     * @return 
     */
    @Override
    public Prototype clone() {
        try {
            Prototype clone = (Prototype) super.clone();
            clone.list = new ArrayList<>(); // 主动创建一个新的list对象,实现深克隆
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
     
}

自己动手实现深克隆:

/**
 * 自己动手,不需要实现接口:java.lang.Cloneable
 */
public class Prototype {
    
    public int number = 10;

    public List<String> list = new ArrayList<>();
    
    /**
     * 因为没有使用父类clone()方法,所以自定义一个其它的方法名,不使用clone
     * 
     * @return 
     */
    public Prototype cloneObject() {
        Prototype clone = new Prototype();
        clone.number = this.number;
        clone.list = new ArrayList<>(); // 区别就在这里,深克隆要把原型内部持有对象全都重新创建一遍
        return clone;
    }
    
}

上述两种方法都能实现深克隆操作,克隆对象和原型对象持有的list属性对象不是同一个。

总结

原型模式是一个很简单的设计模式,清楚理解浅克隆深克隆的区别很重要。

很多开源工具包里都提供有复制对象的工具类,先搞清楚它们是浅克隆复制还是深克隆复制,然后再根据实际业务场景选择使用即可。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值