设计模式之原型
原型模式介紹
完整拷貝原型模式主要解決的問題就是創(chuàng)建重復(fù)對象,而這部分對象內(nèi)容本身比較復(fù)雜,生成過程可能從庫或者RPC接口中獲取數(shù)據(jù)的耗時較長,因此采用克隆的方式節(jié)省時間。
原型模式是一種創(chuàng)建型設(shè)計模式,使你能夠復(fù)制已有對象,而無需使代碼依賴它們所屬的類。
原型模式的特點
在原型模式中所需要非常重要的手段就是克隆。
原型模式的使用頻率不是很高。
在一個很復(fù)雜的類層次中,當(dāng)系統(tǒng)必須從其中的許多類型創(chuàng)建新對象時,可以考慮用原型。
便于通過克隆方式創(chuàng)造復(fù)雜對象,也可以避免重復(fù)做初始化操作,不需要與類中所屬的其他類耦合。
優(yōu)點:
向客戶隱藏制造新實例的復(fù)雜性
提供讓客戶能夠產(chǎn)生未知類型對象的選項
在某些環(huán)境下,復(fù)制對象比創(chuàng)建新對象更有效
可以用繼承以外的方式來處理復(fù)雜對象的不同配置
缺點:
對象的復(fù)制有時候很復(fù)雜
原型模式的結(jié)構(gòu)
1、原型(Prototype)接口將對克隆進(jìn)行聲明。在絕大數(shù)情況下,其中只會有一個名為clone的方法。
2、具體原型(Concrete Prototype)類將實現(xiàn)克隆方法。除了將原始對象的數(shù)據(jù)復(fù)制到克隆體中之外,該方法有時還需處理克隆過程中的極端情況,例如克隆關(guān)聯(lián)對象和梳理遞歸依賴等等。
3、客戶端(Client)可以復(fù)制實現(xiàn)了原型接口的任何對象。
所有的原型類都必須有一個通用的接口,使得即使在對象所屬的具體類未知的情況下也能復(fù)制對象。原型對象可以生產(chǎn)自身的完整副本,因為相同類的對象可以相互訪問對方的私有成員變量。
Demo
下面就以學(xué)生信息為例來簡單學(xué)習(xí)下原型模式。入校時填寫學(xué)生信息都是重復(fù)且簡單的工作,如果我們把格式規(guī)定好,其余的學(xué)生按照一定的格式來編寫,那么就可以使用原型模式。
????public?class?Student{public?int?Age;public?DateTime?BirthDate;public?string?Name;public?IdInfo?IdInfo;///?<summary>///?淺拷貝///?</summary>///?<returns></returns>public?Student?ShallowCopy()?{return?(Student)this.MemberwiseClone();}///?<summary>///?深拷貝///?</summary>///?<returns></returns>public?Student?DeepCopy(){Student?clone?=?(Student)this.MemberwiseClone();clone.IdInfo?=?new?IdInfo(IdInfo.IdNumber);clone.Name?=?String.Copy(Name);return?clone;}} ????public?class?IdInfo?{public?int?IdNumber;public?IdInfo(int?id){IdNumber?=?id;}????} ????????static?void?Main(string[]?args){Student?student=new?Student();student.Name?=?"阿輝";student.BirthDate?=?Convert.ToDateTime("1990-10-08");student.Age?=?27;student.IdInfo?=?new?IdInfo(001);Student?studentTwo?=?student.ShallowCopy();var?studentThree?=?student.DeepCopy();Console.WriteLine("學(xué)生信息");Console.WriteLine("One");DisplayValues(student);Console.WriteLine("Two");DisplayValues(studentTwo);Console.WriteLine("Three");DisplayValues(studentThree);Console.WriteLine("--------------------------");student.Name?=?"阿七";student.Age?=?18;student.BirthDate?=?Convert.ToDateTime("2018-10-08");student.IdInfo.IdNumber?=?002;Console.WriteLine("修改后學(xué)生信息");Console.WriteLine("One");DisplayValues(student);Console.WriteLine("Two");DisplayValues(studentTwo);Console.WriteLine("Three");DisplayValues(studentThree);Console.ReadKey();}public?static?void?DisplayValues(Student?s){Console.WriteLine("??????Name:?{0:s},?Age:?{1:d},?BirthDate:?{2:MM/dd/yy}",s.Name,?s.Age,?s.BirthDate);Console.WriteLine("??????ID:?{0:d}",?s.IdInfo.IdNumber);} 輸出結(jié)果解釋:
可以看到在第一次創(chuàng)建學(xué)生對象的時候淺拷貝和深拷貝的值都是一樣的,和原始值一樣。
當(dāng)我們修改學(xué)生信息時,學(xué)生阿輝被修改為阿七,其余屬性也被覆蓋進(jìn)行修改。此時看淺拷貝和深拷貝的數(shù)據(jù),發(fā)現(xiàn)在淺拷貝的時候只有ID值被修改,其余值還和原數(shù)據(jù)一樣,在深拷貝中輸出的所有數(shù)據(jù)都和原始值一樣,也就是說修改的數(shù)據(jù),根本沒有對深拷貝的數(shù)據(jù)進(jìn)行覆蓋,深拷貝是對原始值的復(fù)制。
所有的原型類都必須有一個通用的接口,使得即使在對象所屬的具體類未知的情況下也能復(fù)制對象。原型對象可以生成自身的完整副本,因為相同類的對象可以相互訪問對方的私有成員變量。
對于上面這句話,你品,你細(xì)品。
雖然說原型模式使用的頻次不是很多,但是我們需要大概知道如何使用,為什么使用。
小寄語
人生短暫,我不想去追求自己看不見的,我只想抓住我能看的見的。
我是阿輝,感謝您的閱讀,如果對你有幫助,麻煩點贊、轉(zhuǎn)發(fā) ?謝謝。
總結(jié)
- 上一篇: 谈谈为什么我们需要云原生架构?
- 下一篇: 如何入门.NET Core ? 推荐这1