定義
原型模式(Prototype Pattern)是指原型實例指定創(chuàng)建對象的 種類,并且通過拷貝這些原型創(chuàng)建新的對象。調(diào)用者不需要知道任何創(chuàng)建細節(jié),不調(diào)用構(gòu)造函數(shù)。適用場景
類初始化消耗資源較多。new產(chǎn)生的一個對象需要非常繁瑣的過程(數(shù)據(jù)準備、訪問權(quán)限等)構(gòu)造函數(shù)比較復(fù)雜循環(huán)體中生產(chǎn)大量對象時,可讀性下降。原型模式就是快速構(gòu)建對象的方法總結(jié), 簡單工廠將getter、tter封裝到某個方法中 JDK提供的實現(xiàn)Cloneable接口,實現(xiàn)快速復(fù)制 scope=“prototype”,scope=”singleton”優(yōu)點
原型模式性能比直接new一個對象性能高簡化了創(chuàng)建過程缺點
必須配備克隆(或者可拷貝)方法對克隆復(fù)雜對象或?qū)寺〕龅膶ο筮M行復(fù)雜改造時,易帶來風(fēng)險深拷貝、淺拷貝要運用得當實例
簡單克隆
創(chuàng)建原型Prototype接口
public interface Prototype{ Prototype clone();}
創(chuàng)建具體需要克隆的對象ConCretePrototype
public class ConcretePrototypeA implements Prototype { private int age; private String name; private List hobbies;? public int getAge() { return age; }? public void tAge(int age) { this.age = age; }? public String getName() { return name; }? public void tName(String name) { this.name = name; }? public List getHobbies() { return hobbies; }? public void tHobbies(List hobbies) { this.hobbies = hobbies; }? @Override public ConcretePrototypeA clone() { ConcretePrototypeA concretePrototype = new ConcretePrototypeA(); concretePrototype.tAge(this.age); concretePrototype.tName(this.name); concretePrototype.tHobbies(this.hobbies); return concretePrototype; }?}
創(chuàng)建client對象
public class Client {? private Prototype prototype;? public Client(Prototype prototype){ this.prototype = prototype; } public Prototype startClone(Prototype concretePrototype){ return (Prototype)concretePrototype.clone(); }?}
測試實例
// 創(chuàng)建一個具體的需要克隆的對象 ConcretePrototypeA concretePrototype = new ConcretePrototypeA(); // 填充屬性,方便測試 concretePrototype.tAge(18); concretePrototype.tName("prototype"); List hobbies = new ArrayList<String>(); concretePrototype.tHobbies(hobbies); System.out.println(concretePrototype);? // 創(chuàng)建Client對象,準備開始克隆 Client client = new Client(concretePrototype); ConcretePrototypeA concretePrototypeClone = (ConcretePrototypeA) client.startClone(concretePrototype); System.out.println(concretePrototypeClone);? System.out.println("克隆對象中的引用類型地址值:" + concretePrototypeClone.getHobbies()); System.out.println("原對象中的引用類型地址值:" + concretePrototype.getHobbies()); System.out.println("對象地址比較:"+(concretePrototypeClone.getHobbies() == concretePrototype.getHobbies()));
運行結(jié)果
從測試結(jié)果看出 hobbies 的引用地址是相同的,意味著復(fù)制的不是值,而是引用的地址。 這 樣 的 話 , 如 果 我 們 修 改 任 意 一 個 對 象 中 的 屬 性 值 , concretePrototype 和 concretePrototypeCone 的 hobbies 值都會改變。這就是我們常說的淺克隆。只是完整 復(fù)制了值類型數(shù)據(jù),沒有賦值引用對象。
深度克隆
? ?我們換一個場景,大家都知道齊天大圣。首先它是一只猴子,有七十二般變化,把一根毫毛就可以吹出千萬個潑猴,手里還拿著金箍棒,金箍棒可以變大變小。這就是我們耳 熟能詳?shù)脑湍J降慕?jīng)典體現(xiàn)。
創(chuàng)建猴子Monkey類
public class Monkey { public int height; public int weight; public Date birthday;?}
創(chuàng)建金箍棒類
public class JinGuBang implements Serializable { public float h = 100; public float d = 10;? public void big(){ this.d *= 2; this.h *= 2; }? public void small(){ this.d /= 2; this.h /= 2; }}
創(chuàng)建對象齊天大圣類
public class QiTianDaSheng extends Monkey implements Cloneable,Serializable {? public JinGuBang jinGuBang;? public QiTianDaSheng(){ //只是初始化 this.birthday = new Date(); this.jinGuBang = new JinGuBang(); }? @Override protected Object clone() throws CloneNotSupportedException { return this.deepClone(); }?? public Object deepClone(){ try{? ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this);? ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis);? QiTianDaSheng copy = (QiTianDaSheng)ois.readObject(); copy.birthday = new Date(); return copy;? }catch (Exception e){ e.printStackTrace(); return null; }? }?? public QiTianDaSheng shallowClone(QiTianDaSheng target){? QiTianDaSheng qiTianDaSheng = new QiTianDaSheng(); qiTianDaSheng.height = target.height; qiTianDaSheng.weight = target.height;? qiTianDaSheng.jinGuBang = target.jinGuBang; qiTianDaSheng.birthday = new Date(); return qiTianDaSheng; }
測試類
QiTianDaSheng qiTianDaSheng = new QiTianDaSheng(); try { QiTianDaSheng clone = (QiTianDaSheng)qiTianDaSheng.clone(); System.out.println("深克隆:" + (qiTianDaSheng.jinGuBang == clone.jinGuBang)); } catch (Exception e) { e.printStackTrace(); }? QiTianDaSheng q = new QiTianDaSheng(); QiTianDaSheng n = q.shallowClone(q); System.out.println("淺克隆:" + (q.jinGuBang == n.jinGuBang));
運行結(jié)果
本文發(fā)布于:2023-02-28 21:36:00,感謝您對本站的認可!
本文鏈接:http://www.newhan.cn/zhishi/a/1677776169118599.html
版權(quán)聲明:本站內(nèi)容均來自互聯(lián)網(wǎng),僅供演示用,請勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請與我們聯(lián)系,我們將在24小時內(nèi)刪除。
本文word下載地址:jingubang(金箍棒有多少斤).doc
本文 PDF 下載地址:jingubang(金箍棒有多少斤).pdf
| 留言與評論(共有 0 條評論) |