设计模式-原型模式

原型模式

原型模式是23种设计模式之一,和单例模式一样,相对其他设计模式较为容易理解。

定义

原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。[1]

       原型模式通过克隆一个已经存在的对象实例来返回新的实例,而不是通过new去创建对象,多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效。在Java中,复制对象是通过原型对象实现Cloneable接口,重写clone()方法实现的

 

在实际开发中我们也经常使用克隆方法,下面是我在工作中遇到的案例,业务非常的简单

业务需求:

       要求对数据的update,modify,delete的操作,都需要备份原始数据,提高业务的容错性

解决方案:

       操作数据前先根据主键或唯一字段查出数据,再用BeanUtils.copyProperties(source, target)方法克隆出一个新的类

注:这里我们调用了BeanUtils中的copyProperties(source, target)方法来进行数据的复制。当然你也可以使用原始的get和set的方法进行数据的复制,但是当类中的字段相当庞大时,原始的办法就显得相当的繁琐。

//修改数据源信息
@Transactional
public void modifyDbConf(TMdDbConfig dbConfig) {
	//根据confName查询旧数据
	String confName = dbConfig.getConfName();
	TMdDbConfig olDbConfig = tmdDbConfigMapper.selectByPrimaryKey(confName);
	TMdDbConfigLog dbLog = new TMdDbConfigLog();
	//封装数据
	BeanUtils.copyProperties(olDbConfig, dbLog);
	dbLog.setOperator(dbConfig.getModifier());
	dbLog.setOperationTime(dbConfig.getModifyTime());
	
	tmdDbConfigMapper.saveDbLog(dbLog);
	tmdDbConfigMapper.modifyDbConf(dbConfig);
}

下面我们来讲讲原型模式的简单实现

对象的克隆分为2种:浅可怜和深度克隆

/**
 * @description:浅克隆(浅复制)
 */
public  class ShallowClone implements Cloneable,Serializable{

    private String name;
    private int age;
    List<String> hobbies = new ArrayList<>();

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 重写clone方法
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object clone = null;
        try {
            clone = super.clone();
        }catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

}

浅克隆

创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址

测试代码

 public static void main(String[] args) {
        ShallowClone shallowClone = new ShallowClone();
        shallowClone.setName("Tom");
        shallowClone.setAge(18);
        shallowClone.setHobbies(new ArrayList<>());
        ShallowClone clone = null;
        try {
            clone = (ShallowClone)shallowClone.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        System.out.println(shallowClone == clone);//false
        System.out.println(clone.getName());//Tom
        System.out.println(clone.getAge());//18
        System.out.println(shallowClone.getHobbies()==clone.getHobbies());//true

    }

 

深克隆

       创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址

测试代码

public static void main(String[] args) throws Exception{

        //将对象写到流里
        ShallowClone shallowClone = new ShallowClone();
        shallowClone.setName("Tom");
        shallowClone.setAge(18);
        shallowClone.setHobbies(new ArrayList<>());
        ByteArrayOutputStream byteOut=new ByteArrayOutputStream();
        ObjectOutputStream objOut=new ObjectOutputStream(byteOut);
        objOut.writeObject(shallowClone);
        //从流里读出来
        ByteArrayInputStream byteIn=new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream objInput=new ObjectInputStream(byteIn);
        ShallowClone clone = (ShallowClone) objInput.readObject();

        System.out.println(clone.getName());//Tom
        System.out.println(clone.getAge());18
        System.out.println(clone.getName() == shallowClone.getName());//false
        System.out.println(clone.getHobbies() == shallowClone.getHobbies());//false
    }

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.  "The Prototype design pattern - Problem, Solution, and Applicability". w3sDesign.com. Retrieved 2017-08-17.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值