原型模式
1、 原型模式(Prototype)
1.1、 什么是原型模式
通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的办法
创建出更多的同类型的对象。
那么如何“复制”?大多数情况使用Object的clone()方法。或者用流复制。
1.2、 结构
原型模式有两种表现形式:简单形和登记形。
1.2.1、简单形
客户端(Client)角色:客户端提出创建对象的请求
抽象原型(Prototype)角色:给出所有具体原型类所需的接口。可以是接口或者抽象类。
具体原型(Concrete Prototype)角色:被复制的对象,实现抽象原型角色接口。
抽象原型角色:
/** * 抽象原型角色 */ public interface Prototype extends Cloneable{ /** * 提供一个复制对象的方法 */ Prototype clone(); }
具体原型角色:
/** * 具体原型角色 */ public class ConcretePrototype implements Prototype{ @Override public Prototype clone() { try { return (Prototype) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return null; } }
客户端角色:
/** * 客户端角色 */ public class Client { private Prototype prototype; public void operation(Prototype example){ Prototype p = example.clone(); } }
1.2.2、登记形
客户端(Client)角色:向管理员提出创建对象的请求。
抽象原型(Prototype)角色:给出所有具体原型类所需的接口。可以是接口或者抽象类。
具体原型(Concrete Prototype)角色:被复制的对象,实现抽象原型角色接口。
原型管理器(Prototype Manager)角色:创建具体原型类的对象,并记录每一个被创建的对象。
抽象原型角色:
/** * 抽象原型角色 */ public interface Prototype extends Cloneable{ /** * 提供一个复制对象的方法 */ Object clone(); }
具体原型角色:
/** * 具体原型角色 */ public class ConcretePrototype implements Prototype{ @Override synchronized public Object clone() { Prototype temp = null; try { temp = (Prototype) super.clone(); return temp; } catch (CloneNotSupportedException e) { e.printStackTrace(); }finally { return temp; } } }
原型管理器类:
/** * 原型管理器类 */ public class PrototypeManager{ private Vector objects = new Vector(); /** * 新增对象 */ public void add(Prototype object){ objects.add(object); } /** * 获取对象 */ public Prototype get(int i){ return (Prototype) objects.get(i); } /** * 查询集合大小 */ public int getSize(){ return objects.size(); } }
客户端角色:
/** * 客户端角色 */ public class Client { private PrototypeManager mgr; private Prototype prototype; public void registerPrototype(){ prototype = new ConcretePrototype(); Prototype copyType = (Prototype) prototype.clone(); mgr.add(copyType); } }
1.3、浅复制
浅复制仅仅复制所考虑的对象,而不是复制它所引用的对象。
对象是在堆中产生的,对象中的类变量的基础类型的值在这个对象本身的内存空间中,引用类型则在这个对象中存放一个引用地址或称为指针的东西,指向了另一个对象在内存中的位置。复制出来的对象中的引用类型变量指向了被复制对象的引用类型变量地址。
1.4、深复制
深复制是将被复制对象完全拷贝过来。在内存中形成一个新的,无任何引用关系的对象。
被复制对象的引用类型对象也会重新再内存中创建一个新对象。
1.7、小结
原型模式会复制出一个新的对象。为什么用复制而不是用new呢?new的过程太复杂,而且需要消耗很多资源,如需要多次的数据库访问。新对象与原对象的大部分值是相等的,且新对象的值会被修改。