@linux1s1s
2019-02-18T11:27:53.000000Z
字数 3180
阅读 1887
Base 2017-01
在阎宏博士的《JAVA与模式》一书中开头是这样描述原型(Prototype)模式的:
原型模式属于对象的创建模式。通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。这就是选型模式的用意。
为了表达清楚上面枯燥的表达,我们用UML类图来说明一下:

接下来看看源码:
public interface Contract {Contract clone();String getName();void setName(String name);}
public class PrototypeA implements Contract {private String name;@Overridepublic Contract clone() {PrototypeA a = new PrototypeA();a.setName(name);return a;}@Overridepublic String getName() {return name;}@Overridepublic String toString() {return "PrototypeA " + "[hashcode=" + hashCode() + "] " + "[name=" + name + "]";}@Overridepublic void setName(String name) {this.name = name;}}
public class PrototypeB implements Contract {private String name;@Overridepublic Contract clone() {PrototypeB b = new PrototypeB();b.setName(name);return b;}@Overridepublic String toString() {return "PrototypeB " + "[hashcode=" + hashCode() + "] " + "[name=" + name + "]";}@Overridepublic String getName() {return name;}@Overridepublic void setName(String name) {this.name = name;}}
public class PrototypeManager {private static PrototypeManager INSTANCE;private final Map<String, Contract> mContracts;private PrototypeManager() {mContracts = new HashMap<String, Contract>();}public static PrototypeManager getInstance() {if (INSTANCE == null) {synchronized (PrototypeManager.class) {if (INSTANCE == null) {INSTANCE = new PrototypeManager();}}}return INSTANCE;}public boolean put(String id, Contract c) {if (TextUtils.isEmpty(id) || c == null) {return false;}if (mContracts.containsKey(id)) {return false;}mContracts.put(id, c);return true;}public Contract get(String id) {if (TextUtils.isEmpty(id)) {return null;}return mContracts.get(id);}public boolean remove(String id) {if (TextUtils.isEmpty(id)) {return false;}if (!mContracts.containsKey(id)) {return true;}mContracts.remove(id);return true;}}
public class TestCase {public static void exe() {try {Contract c1 = new PrototypeA();PrototypeManager.getInstance().put("p1", c1);// 获取原型来创建对象Contract c3 = PrototypeManager.getInstance().get("p1").clone();c3.setName("susan");Log.i("Prototype", "第一个实例:" + c3);// 有人动态的切换了实现Contract c2 = new PrototypeB();PrototypeManager.getInstance().put("p1", c2);// 重新获取原型来创建对象Contract c4 = PrototypeManager.getInstance().get("p1").clone();c4.setName("bili");Log.i("Prototype", "第二个实例:" + c4);// 有人注销了这个原型PrototypeManager.getInstance().remove("p1");// 再次获取原型来创建对象Contract c5 = PrototypeManager.getInstance().get("p1").clone();c5.setName("coqi");Log.i("Prototype", "第三个实例:" + c5);} catch (NullPointerException e) {// TODO: handle exception}}}
01-11 06:17:03.053 13654-13654/? I/Prototype: 第一个实例:PrototypeA [hashcode=1384349684] [name=susan]01-11 06:17:03.057 13654-13654/? I/Prototype: 第二个实例:PrototypeA [hashcode=1384350260] [name=bili]
public Object deepClone() throws IOException, ClassNotFoundException{//将对象写到流里ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);//从流里读回来ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return ois.readObject();}
原型模式要求对象实现一个可以“克隆”自身的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例。这样一来,通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无须再去通过new来创建。
参考博文:
《JAVA与模式》之原型模式
