elasticsearch入門系列">elasticsearch入門系列
605
2022-05-29
前言
設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 毫無疑問,設計模式于己于他人于系統都是多贏的,設計模式使代碼編制真正工程化,設計模式是軟件工程的基石,如同大廈的一塊塊磚石一樣。項目中合理的運用設計模式可以完美的解決很多問題,每種模式在現在中都有相應的原理來與之對應,每一個模式描述了一個在我們周圍不斷重復發生的問題,以及該問題的核心解決方案,這也是它能被廣泛應用的原因。
提示:以下是本篇文章正文內容,下面案例可供參考
一、原型模式(Prototype Pattern)
原型模式屬于創建型模式,使用原型實例指定待創建對象的類型,并且通過復制這個原型來創建新的對象。
原型模式關注的是大量相同或相似對象的創建問題。應用原型模式就是建立一個原型,然后通過對原型來進行復制的方法,產生一個和原型相同或相似的新對象。
二、使用步驟
角色
1、抽象原型(Prototype)
聲明一個克隆自身的接口,通常名為Clone;
2、具體原型(Concrete Prototype)
實現一個克隆自身的操作,包含深拷貝和淺拷貝。
淺克隆(Shallow Clone):當原型對象被復制時,只復制它本身和其中包含的值類型的成員變量,而引用類型的成員變量并沒有復制,它們只是指向同一個引用。
深克隆(Deep Clone):除了對象本身被復制外,對象所包含的所有成員變量也將被復制,它們擁有不同的副本。
注:C#中的MemberwiseClone屬于淺克隆。
示例
命名空間PrototypePattern包含細胞基類Cell,它的2個實現類分別為:PlantCell植物細胞類和Animal動物細胞類,另外包含CloneBase泛型基類。本案例嘗試模擬細胞的分裂過程以展示原型模式在復制對象本身方面的獨到之處。
[Serializable] public abstract class Cell : CloneBase
抽象細胞基類Cell,繼承自CloneBase并定義Division分裂接口。
[Serializable] public class PlantCell : Cell { public PlantCell(int id, string wall, string membrane, string cytoplasm, string nucleus) : base(id, wall, membrane, cytoplasm, nucleus) { } public override Cell Division() { var cell = this.MemberwiseClone() as Cell; cell.Id = RandomUtil.RandomNum(); return cell; } }
植物細胞類PlantCell,細胞基類的具體實現類,標記Serializable特性以支持序列化的深克隆。
[Serializable] public class AnimalCell : Cell { public AnimalCell(int id, string wall, string membrane, string cytoplasm, string nucleus) : base(id, wall, membrane, cytoplasm, nucleus) { } public override Cell Division() { var cell = this.MemberwiseClone() as Cell; cell.Id = RandomUtil.RandomNum(); return cell; } }
動物細胞類AnimalCell,細胞基類的具體實現類,標記Serializable特性以支持序列化的深克隆。
[Serializable] public class Content { public string Mitochondria { get; set; }//線粒體 public int Chloroplasts { get; set; }//葉綠體 public int EndoplasmicReticulum { get; set; }//內質網 public int GolgiBody { get; set; }//高爾基復合體 public int Ribosomes { get; set; }//核糖體 public int Centrosome { get; set; }//中心體 public int Vacuole { get; set; }//液泡 public int Lysosomes { get; set; }//溶酶體 public int Microtubule { get; set; }//微管 }
細胞質類Content,為細胞基類中所包含的一個對象成員。
[Serializable] public class CloneBase
克隆類CloneBase,包含一個虛擬的Clone方法以支持深克隆。
public class RandomUtil { public static int RandomNum() { return new Random().Next(1000000, 10000000); } }
產生細胞Id的工具類,從100萬到1000萬。
public class Program { private static Cell _cell = null; private const string SPLIT_BREAK = "-----------------------------------------------------"; public static void Main(string[] args) { _cell = new PlantCell(RandomUtil.RandomNum(), "wall", "membrane", "cytoplasm", "nucleus"); var plant = _cell.Division(); Console.WriteLine($"_cell.GUID:{_cell.Id},{Environment.NewLine}plant.GUID:{plant.Id}," + $"{Environment.NewLine}equals:{_cell.Id == plant.Id}."); Console.WriteLine(SPLIT_BREAK); _cell.Content.Mitochondria = "10010101010100101010101"; Console.WriteLine($"_cell.Content.Mitochondria:{_cell.Content.Mitochondria},\r\n" + $"plant.Content.Mitochondria:{plant.Content.Mitochondria}," + $"{Environment.NewLine}equals:" + $"{_cell.Content.Mitochondria == plant.Content.Mitochondria}."); Console.WriteLine(SPLIT_BREAK); var animal = _cell.Clone(); Console.WriteLine($"_cell.GUID:{_cell.Id},{Environment.NewLine}animal.GUID:{animal.Id}," + $"{Environment.NewLine}equals:{_cell.Id == animal.Id}."); Console.WriteLine(SPLIT_BREAK); _cell.Content.Mitochondria = "01001010010100101010010"; Console.WriteLine($"_cell.Content.Mitochondria:{_cell.Content.Mitochondria},\r\n" + $"animal.Content.Mitochondria:{animal.Content.Mitochondria}," + $"{Environment.NewLine}equals:" + $"{_cell.Content.Mitochondria == animal.Content.Mitochondria}."); Console.WriteLine(SPLIT_BREAK); Console.ReadKey(); } }
以上是調用方的代碼,植物細胞實例調用了淺克隆,而動物細胞實例調用了深克隆,請仔細分析這段代碼。以下是這個案例的輸出結果:
_cell.GUID:6768270, plant.GUID:2028096, equals:False. ----------------------------------------------------- _cell.Content.Mitochondria:10010101010100101010101, plant.Content.Mitochondria:10010101010100101010101, equals:True. ----------------------------------------------------- _cell.GUID:6768270, animal.GUID:6768270, equals:True. ----------------------------------------------------- _cell.Content.Mitochondria:01001010010100101010010, animal.Content.Mitochondria:10010101010100101010101, equals:False. -----------------------------------------------------
總結
優點
1、原型模式向客戶隱藏了創建新實例的復雜性;
2、原型模式允許動態增加或較少產品類;
3、原型模式簡化了實例的創建結構,工廠方法模式需要有一個與產品類等級結構相同的等級結構,而原型模式不需要這樣;
4、產品類不需要事先確定產品的等級結構,因為原型模式適用于任何的等級結構。
缺點
1、每個類必須配備一個克隆方法或繼承自CloneBase泛型類;
2、配備克隆方法需要對類的功能進行通盤考慮,這對于全新的類不是很難,但對于已有的類不一定很容易,特別當一個類引用不支持串行化的間接對象,或者引用含有循環結構的時候。
使用場景
1、 當一個系統應該獨立于它的產品創建、構成和表示時;
2、當要實例化的類是在運行時刻指定時,例如通過動態裝載來創建一個類;
3、為了避免創建一個與產品類層次平行的工廠類層次時;
4、當一個類的實例只能有幾個不同狀態組合中的一種時。建立相應數目的原型并Clone它們可能比每次用合適的狀態手工實例化該類更方便一些。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。