设计模式之原型
原型模式介紹
完整拷貝原型模式主要解決的問題就是創建重復對象,而這部分對象內容本身比較復雜,生成過程可能從庫或者RPC接口中獲取數據的耗時較長,因此采用克隆的方式節省時間。
原型模式是一種創建型設計模式,使你能夠復制已有對象,而無需使代碼依賴它們所屬的類。
原型模式的特點
在原型模式中所需要非常重要的手段就是克隆。
原型模式的使用頻率不是很高。
在一個很復雜的類層次中,當系統必須從其中的許多類型創建新對象時,可以考慮用原型。
便于通過克隆方式創造復雜對象,也可以避免重復做初始化操作,不需要與類中所屬的其他類耦合。
優點:
向客戶隱藏制造新實例的復雜性
提供讓客戶能夠產生未知類型對象的選項
在某些環境下,復制對象比創建新對象更有效
可以用繼承以外的方式來處理復雜對象的不同配置
缺點:
對象的復制有時候很復雜
原型模式的結構
1、原型(Prototype)接口將對克隆進行聲明。在絕大數情況下,其中只會有一個名為clone的方法。
2、具體原型(Concrete Prototype)類將實現克隆方法。除了將原始對象的數據復制到克隆體中之外,該方法有時還需處理克隆過程中的極端情況,例如克隆關聯對象和梳理遞歸依賴等等。
3、客戶端(Client)可以復制實現了原型接口的任何對象。
所有的原型類都必須有一個通用的接口,使得即使在對象所屬的具體類未知的情況下也能復制對象。原型對象可以生產自身的完整副本,因為相同類的對象可以相互訪問對方的私有成員變量。
Demo
下面就以學生信息為例來簡單學習下原型模式。入校時填寫學生信息都是重復且簡單的工作,如果我們把格式規定好,其余的學生按照一定的格式來編寫,那么就可以使用原型模式。
????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("學生信息");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("修改后學生信息");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);} 輸出結果解釋:
可以看到在第一次創建學生對象的時候淺拷貝和深拷貝的值都是一樣的,和原始值一樣。
當我們修改學生信息時,學生阿輝被修改為阿七,其余屬性也被覆蓋進行修改。此時看淺拷貝和深拷貝的數據,發現在淺拷貝的時候只有ID值被修改,其余值還和原數據一樣,在深拷貝中輸出的所有數據都和原始值一樣,也就是說修改的數據,根本沒有對深拷貝的數據進行覆蓋,深拷貝是對原始值的復制。
所有的原型類都必須有一個通用的接口,使得即使在對象所屬的具體類未知的情況下也能復制對象。原型對象可以生成自身的完整副本,因為相同類的對象可以相互訪問對方的私有成員變量。
對于上面這句話,你品,你細品。
雖然說原型模式使用的頻次不是很多,但是我們需要大概知道如何使用,為什么使用。
小寄語
人生短暫,我不想去追求自己看不見的,我只想抓住我能看的見的。
我是阿輝,感謝您的閱讀,如果對你有幫助,麻煩點贊、轉發 ?謝謝。
總結
- 上一篇: 谈谈为什么我们需要云原生架构?
- 下一篇: 如何入门.NET Core ? 推荐这1