原型模式(Prototype)

定义

  用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

UML结构图

  

浅复制

  ProtoType

package com.csdhsm.pattemdesign.prototype;

import java.util.ArrayList;
import java.util.List;

/**  
 * @Title:  Prototype.java   
 * @Description: 浅复制
 * @author: Han   
 * @date:   2016年6月21日 下午9:09:28  
 */  
public class Prototype implements Cloneable {
    
    private String name;
    private List<String> list = new ArrayList<>();
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public void add(String str) {
        this.list.add(str);
    }
    
    public List<String> getList() {
        return list;
    }
    
    public void setList(List<String> list) {
        this.list = list;
    }
    
    //克隆方法返回对象
    @Override
    protected Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

  客户端

package com.csdhsm.pattemdesign.prototype;

public class Solution {

    public static void main(String[] args) {

        Prototype pro = new Prototype();
        pro.setName("original object");
        pro.add("original object1");
        Prototype pro1 = (Prototype) pro.clone();
        pro1.setName("changed object1");
        pro1.add("original object2");

        System.out.println("original object:" + pro.getName());
        System.out.println("cloned object:" + pro1.getName());
        System.out.println("original object:" + pro.getList());
        System.out.println("cloned object:" + pro1.getList());
    }
}

  结果

问题分析

  在基本数据类型(int,double,float...)和String对象时,这种复制是没有什么问题的,因为浅复制只对值进行复制,如果是引用类型变量(例如List,Person...)时,只会复制引用,也就是说,在内存里,复制前和复制后在内存里是指向同一个实例,所以在上个例子中,对于List对象,复制后生成的对象添加数据,会引起原对象的变化,这就是所谓的深复制和浅复制的区别。

深复制

  ProtoType

package com.csdhsm.pattemdesign.prototype;

import java.util.ArrayList;

/**  
 * @Title:  Prototype.java   
 * @Description: 深复制
 * @author: Han   
 * @date:   2016年6月21日 下午9:09:28  
 */  
public class Prototype implements Cloneable {
    
    private String name;
    private ArrayList<String> list = new ArrayList<>();
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public void add(String str) {
        this.list.add(str);
    }
    
    public ArrayList<String> getList() {
        return list;
    }
    
    public void setList(ArrayList<String> list) {
        this.list = list;
    }
    
    //克隆方法返回对象
    @SuppressWarnings("unchecked")
    @Override
    protected Object clone() {
        Prototype pro2 = null;
        try {
            pro2 = (Prototype) super.clone();
            //深复制重点在这句代码,重新新生成一个对象,赋给新对象的list
            pro2.setList((ArrayList<String>) this.list.clone());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return pro2;
    }
}

  客户端代码不变

  结果

  OK,深复制成功!

 posted on 2016-06-21 21:52  韩思明  阅读(171)  评论(0编辑  收藏  举报