2018-1-12 by Atlasjava
經過給出一個原型對象來指明所要建立的對象的類型,而後用複製這個原型對象的方法建立出更多同類型的對象。原始模型模式容許動態的增長或減小產品類,產品類不須要非得有任何事先肯定的等級結構,原始模型模式適用於任何的等級結構。缺點是每個類都必須配備一個克隆方法。框架
(1)種類過多沒法整合成類時。
(2)不容易利用類產生對象實例時。
(3)但願把框架和所產生的對象實例分開時。ide
- Prototype(原型) 參與者
Prototype參與者規定複製(copy)對象實例再創建新對象實例的方法。- ConcretePrototype(具體原型)參與者
ConcretePrototype參與者是實際上實現先複製對象實例再創建新對象實例的方法。- Client(客戶)參與者
Client參與者利用複製對象實例的方法產生另外一個新對象實例。- 原型模式的核心就是複製,表現到java語言就是實現Cloneable,實現clone方法,具體一點,就是clone操做時以原型爲模版,分配原型一樣大小的內存空間,而後建立一個跟原型同樣的對象實例。
public class Prototype implements Cloneable { private int count; private ShallowCopy shallowCopy; private static Prototype prototype = new Prototype(0, new ShallowCopy()); private Prototype(int count, ShallowCopy shallowCopy){ this.count = count; this.shallowCopy = shallowCopy; } public Prototype clone() throws CloneNotSupportedException { Prototype prototype = (Prototype) super.clone(); // prototype.shallowCopy = this.shallowCopy.clone(); return prototype; } public static void main(String[] args) throws CloneNotSupportedException { Prototype p0 = Prototype.prototype; Prototype p1 = p0.clone(); System.out.println(p0 == p1); System.out.println(p0.count == p1.count); System.out.println(p0.shallowCopy == p1.shallowCopy); } } class ShallowCopy implements Cloneable { public ShallowCopy clone() throws CloneNotSupportedException { return (ShallowCopy) super.clone(); } }
- 成員count、shallowCopy的目的是說明clone操做的「淺拷貝」,不是原型模式的必要元素。
- 私有化Prototype目的是模擬不經過new語法建立對象實例,測試時儘可能經過原型複製對象實例,不是原型模式的必要元素。
- System.out.println(p0 == p1);輸出false;說明clone後的對象實例是在內存中開闢的新空間。
- System.out.println(p0.count == p1.count);輸出true;其實對於基本數據類型來講,數值是存放在對象容器中的,既然對象實例是新開闢的內存空間,數值天然也是複製一份。
- System.out.println(p0.shallowCopy == p1.shallowCopy);輸出true;說明clone的原型對象實例中引用的對象的實例並無從新開闢內存進行復制,只是複製了對引用對象實例的引用,即「淺拷貝」。
- // prototype.shallowCopy = this.shallowCopy.clone();解開註釋後,System.out.println(p0.shallowCopy == p1.shallowCopy);輸出false;說明能夠經過對clone對象實例中引用對象一樣執行clone來進行深一些層次的拷貝,可是若是對象實例的引用對象不對引用對象的引用對象顯式執行clone,沒法達到傳遞拷貝,即徹底深拷貝。
- 固然經過IO操做實現序列化、反序列化對象能夠達到深拷貝的效果。
Spring中的原型模式。測試
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable { // ... public static final String SCOPE_DEFAULT = ""; private String scope = SCOPE_DEFAULT; public void setScope(String scope) { this.scope = scope; } public String getScope() { return this.scope; } /** * Return whether this a <b>Singleton</b>, with a single shared instance * returned from all calls. * @see #SCOPE_SINGLETON */ public boolean isSingleton() { return SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope); } /** * Return whether this a <b>Prototype</b>, with an independent instance * returned for each call. * @see #SCOPE_PROTOTYPE */ public boolean isPrototype() { return SCOPE_PROTOTYPE.equals(scope); } /** * Public declaration of Object's {@code clone()} method. * Delegates to {@link #cloneBeanDefinition()}. * @see Object#clone() */ public Object clone() { return cloneBeanDefinition(); } /** * Clone this bean definition. * To be implemented by concrete subclasses. * @return the cloned bean definition object */ public abstract AbstractBeanDefinition cloneBeanDefinition(); // ... }