CV一族,應該很容易理解原型模式的原理,複製,粘貼完後看具體情況是否修改,其實這就是原型模式。
從java的角度看,一般使用原型模式有個明顯的特點,就是實現cloneable的clone()方法。
原型模式,能快速複製出一個與已經存在對象類似的另外一個我們想要的新對象。
1.意圖
用原型執行個體指定建立對象的種類,並且通過拷貝這些原型建立新的對象。
熱門詞彙:複製 深拷貝 淺拷貝
2.結構圖和代碼
它的結構圖非常簡單,我們以Intent為例子:
Intent的clone方法非常簡單:
@Override public Object clone() { return new Intent(this); }
返回一個新的Intent對象。
複製操作分深拷貝和淺拷貝,淺拷貝說白了就是把原對象所有的值和引用直接賦給新對象。深拷貝則不僅把原對象的值賦給新對象,而且會把原對象的引用對象也重新建立一遍再賦給新對象。
我們具體分析一下Intent是淺拷貝還是深拷貝吧:
public Intent(Intent o) { this.mAction = o.mAction; this.mData = o.mData; this.mType = o.mType; this.mPackage = o.mPackage; this.mComponent = o.mComponent; this.mFlags = o.mFlags; //下面幾個是引用對象被重新建立了,是深拷貝 if (o.mCategories != null) { this.mCategories = new HashSet<String>(o.mCategories); } if (o.mExtras != null) { this.mExtras = new Bundle(o.mExtras); } if (o.mSourceBounds != null) { this.mSourceBounds = new Rect(o.mSourceBounds); } }
這裡我們為什麼Intent要重寫Object的clone方法,就與深拷貝有關。
其實我們查看Object的clone()方法源碼和注釋,預設的super.clone()用的就是淺拷貝:
/** * Creates and returns a copy of this {@code Object}. The default * implementation returns a so-called "shallow" copy: It creates a new * instance of the same class and then copies the field values (including * object references) from this instance to the new instance. A "deep" copy, * in contrast, would also recursively clone nested objects. A subclass that * needs to implement this kind of cloning should call {@code super.clone()} * to create the new instance and then create deep copies of the nested, * mutable objects. */ protected Object clone() throws CloneNotSupportedException { if (!(this instanceof Cloneable)) { throw new CloneNotSupportedException("Class doesn't implement Cloneable"); } return internalClone((Cloneable) this); }
這種形式屬於簡單形式的原型模式,如果需要建立的原型數目不固定,可以建立一個原型管理器,在複製原型對象之前,用戶端先在原型管理器中查看
是否存在滿足條件的原型對象,如果有,則直接使用,如果沒有,複製一個,這種稱作登記形式的原型模式。
適用原型模式可以對客戶隱藏產品的具體類,因此減少了客戶知道的名字的數目,此外是客戶無需改變
原型模式的缺陷是每個原型的子類都必須實現Cloneable介面,這個實現起來有時候比較困難。
3. 效果
(1).建立型模式
(2).運行時刻增加和刪除產品
(3).改變只以指定新對象(ctrl+v,然後修改)
(4).改變結構以指定新對象。(類似2,實現不同而已)
(5).減少子類的構造