PS1句:終究還是選擇CSDN來整理發表這幾年的知識點,該文章平行遷移到CSDN。由于CSDN也支持MarkDown語法了,牛逼啊!
【工匠若水 http://blog.csdn.net/yanbober】 瀏覽前1篇《設計模式(創建型)之建造者模式(Builder Pattern)》 http://blog.csdn.net/yanbober/article/details/45338041
要理解原型原型模式必須先理解Java里的淺復制和深復制。有的地方,復制也叫做克隆。Java提供這兩種克隆方式。 由于Java中的提供clone()方法來實現對象的克隆,所以Prototype模式實現1下子變得很簡單。
淺克隆:被克隆對象的所有變量都含有與原來的對象相同的值,而它所有的對其他對象的援用都依然指向原來的對象。換1種說法就是淺克隆僅僅克隆所斟酌的對象,而不克隆它所援用的對象。
深克隆:被克隆對象的所有變量都含有與原來的對象相同的值,但它所有的對其他對象的援用不再是原本的,而這是指向被復制過的新對象。換言之,深復制把要復制的對象的所有援用的對象都復制了1遍,這類叫做間接復制。
克隆必須滿足的條件:
在java中實現clone()應當滿足以上3個條件(前兩個是必須的,第3個是推薦但不強迫的)。
概念: 使用原型實例指定創建對象的種類,并且通過拷貝這些原型創建新的對象。原型模式是1種對象創建型模式。
重點: 原型模式結構重要核心模塊:
實現Cloneable接口
在java語言有1個Cloneable接口,它的作用只有1個,就是在運行時通知虛擬機可以安全地在實現了此接口的類上使用clone方法。在java虛擬機中,只有實現了這個接口的類才可以被拷貝,否則在運行時會拋出CloneNotSupportedException異常。
重寫Object類中的clone方法
Java中,所有類的父類都是Object類,Object類中有1個clone方法,作用是返回對象的1個拷貝,但是其作用域protected類型的,1般的類沒法調用,因此,Prototype類需要將clone方法的作用域修改成public類型。
創建新對象本錢較大(如初始化需要占用較長的時間,占用太多的CPU資源或網絡資源),新的對象可以通過原型模式對已有對象進行復制來取得,如果是類似對象,則可以對其成員變量稍作修改。
如果系統要保存對象的狀態,而對象的狀態變化很小,或對象本身占用內存較少時,可使用原型模式配合備忘錄模式來實現。
需要避免使用分層次的工廠類來創建分層次的對象,并且類的實例對象只有1個或很少的幾個組合狀態,通過復制原型對象得到新實例可能比使用構造函數創建1個新實例更加方便。
package yanbober.github.io;
//實現Cloneable接口,重寫Object類中的clone方法
class MonkeyPrototype implements Cloneable {
@Override
protected MonkeyPrototype clone() throws CloneNotSupportedException {
MonkeyPrototype monkeyPrototype = (MonkeyPrototype) super.clone();
return monkeyPrototype;
}
}
//原型模式實現類
class ConcreteMonkeyPrototype extends MonkeyPrototype {
public void printHasCode() {
System.out.println("ConcreteMonkeyPrototype hascode="+this.hashCode());
}
}
public class Main {
public static void main(String[] args) {
ConcreteMonkeyPrototype type = new ConcreteMonkeyPrototype();
type.printHasCode();
for (int index=0; index<5; index++) {
try {
ConcreteMonkeyPrototype clone = (ConcreteMonkeyPrototype) type.clone();
clone.printHasCode();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
}
運行結果:
ConcreteMonkeyPrototype hascode=356573597
ConcreteMonkeyPrototype hascode=1735600054
ConcreteMonkeyPrototype hascode=21685669
ConcreteMonkeyPrototype hascode=2133927002
ConcreteMonkeyPrototype hascode=1836019240
ConcreteMonkeyPrototype hascode=325040804
使用原型模式復制對象不會調用類的構造方法
由于對象的復制是通過調用Object類的clone方法來完成的,它直接在內存中復制數據,因此不會調用到類的構造方法。不但構造方法中的代碼不會履行,乃至連訪問權限都對原型模式無效。還記得單例模式嗎?單例模式中,只要將構造方法的訪問權限設置為private型,就能夠實現單例。但是clone方法直接疏忽構造方法的權限,所以,單例模式與原型模式是沖突的,在使用時要特別注意。
原型模式優點以下:
原型模式缺點以下:
【工匠若水 http://blog.csdn.net/yanbober】 繼續瀏覽《設計模式(結構型)之適配器模式(Adapter Pattern)》 http://blog.csdn.net/yanbober/article/details/45338829