原型模式

原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”,这个原型是可定制的。

原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效;或者创建值相等,只是命名不一样的同类数据。

UML图

代码举例

原型模式中的拷贝分为"浅拷贝"和"深拷贝":

1、浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象。

public class Prototype {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

public class NewPrototype implements Cloneable {
    private String id;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    private Prototype prototype;
    public Prototype getPrototype() {
        return prototype;
    }
    public void setPrototype(Prototype prototype) {
        this.prototype = prototype;
    }
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}
public class TestMain {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        testPrototype();
    }
    private static void testPrototype() {
        Prototype pro = new Prototype();
        pro.setName("original object");
        NewPrototype newObj = new NewPrototype();
        newObj.setId("test1");
        newObj.setPrototype(pro);

        NewPrototype copyObj = (NewPrototype) newObj.clone();
        copyObj.setId("testCopy");
        copyObj.getPrototype().setName("changed object");

        System.out.println("original object id:" + newObj.getId());
        System.out.println("original object name:" + newObj.getPrototype().getName());

        System.out.println("cloned object id:" + copyObj.getId());
        System.out.println("cloned object name:" + copyObj.getPrototype().getName());
    }
}

运行结果:

original object id:test1
original object name:changed object
cloned object id:testCopy
cloned object name:changed object

2、深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制。

public class Prototype implements Cloneable {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

public class NewPrototype implements Cloneable {
    private String id;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    private Prototype prototype;
    public Prototype getPrototype() {
        return prototype;
    }
    public void setPrototype(Prototype prototype) {
        this.prototype = prototype;
    }
    public Object clone() {
        NewPrototype ret = null;
        try {
            ret = (NewPrototype) super.clone();
            ret.prototype = (Prototype) this.prototype.clone();
            return ret;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

public class TestMain {
    /**
     * @param args
     */
    public static void main(String[] args) {
        testDeepCopy();
    }
    private static void testDeepCopy() {
        Prototype pro = new Prototype();
        pro.setName("original object");
        NewPrototype newObj = new NewPrototype();
        newObj.setId("test1");
        newObj.setPrototype(pro);

        NewPrototype copyObj = (NewPrototype) newObj.clone();
        copyObj.setId("testCopy");
        copyObj.getPrototype().setName("changed object");

        System.out.println("original object id:" + newObj.getId());
        System.out.println("original object name:" + newObj.getPrototype().getName());

        System.out.println("cloned object id:" + copyObj.getId());
        System.out.println("cloned object name:" + copyObj.getPrototype().getName());
    }
}

运行结果:

original object id:test1
original object name:original object
cloned object id:testCopy
cloned object name:changed object

results matching ""

    No results matching ""