愚公系列2021年12月 二十三種設計模式(四)-原型模式

      網友投稿 605 2022-05-29

      前言

      設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 毫無疑問,設計模式于己于他人于系統都是多贏的,設計模式使代碼編制真正工程化,設計模式是軟件工程的基石,如同大廈的一塊塊磚石一樣。項目中合理的運用設計模式可以完美的解決很多問題,每種模式在現在中都有相應的原理來與之對應,每一個模式描述了一個在我們周圍不斷重復發生的問題,以及該問題的核心解決方案,這也是它能被廣泛應用的原因。

      提示:以下是本篇文章正文內容,下面案例可供參考

      一、原型模式(Prototype Pattern)

      原型模式屬于創建型模式,使用原型實例指定待創建對象的類型,并且通過復制這個原型來創建新的對象。

      原型模式關注的是大量相同或相似對象的創建問題。應用原型模式就是建立一個原型,然后通過對原型來進行復制的方法,產生一個和原型相同或相似的新對象。

      二、使用步驟

      角色

      1、抽象原型(Prototype)

      聲明一個克隆自身的接口,通常名為Clone;

      2、具體原型(Concrete Prototype)

      實現一個克隆自身的操作,包含深拷貝和淺拷貝。

      淺克隆(Shallow Clone):當原型對象被復制時,只復制它本身和其中包含的值類型的成員變量,而引用類型的成員變量并沒有復制,它們只是指向同一個引用。

      深克隆(Deep Clone):除了對象本身被復制外,對象所包含的所有成員變量也將被復制,它們擁有不同的副本。

      注:C#中的MemberwiseClone屬于淺克隆。

      【愚公系列】2021年12月 二十三種設計模式(四)-原型模式

      示例

      命名空間PrototypePattern包含細胞基類Cell,它的2個實現類分別為:PlantCell植物細胞類和Animal動物細胞類,另外包含CloneBase泛型基類。本案例嘗試模擬細胞的分裂過程以展示原型模式在復制對象本身方面的獨到之處。

      [Serializable] public abstract class Cell : CloneBase { public int Id { get; set; } public string Wall { get; set; }//細胞壁 public string Membrane { get; set; }//細胞膜 public string Cytoplasm { get; set; }//細胞質 public string Nucleus { get; set; }//細胞核 public Content Content { get; set; } = new Content();//細胞器 public Cell(int id, string wall, string membrane, string cytoplasm, string nucleus) { this.Id = id; this.Wall = wall; this.Membrane = membrane; this.Cytoplasm = cytoplasm; this.Nucleus = nucleus; this.Content = new Content(); } public abstract Cell Division(); }

      抽象細胞基類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 { public virtual T Clone() { var memoryStream = new MemoryStream(); var formatter = new BinaryFormatter(); formatter.Serialize(memoryStream, this); memoryStream.Position = 0; return (T)formatter.Deserialize(memoryStream); } }

      克隆類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小時內刪除侵權內容。

      上一篇:【愚公系列】2021年12月 Redis數據庫-Redis的配置
      下一篇:【鯤鵬應用創新大賽2020-四川賽區】決賽贏家正式出爐!
      相關文章
      久久精品亚洲一区二区三区浴池 | 色天使亚洲综合在线观看| 婷婷亚洲综合五月天小说在线| 久久精品亚洲精品国产色婷| 亚洲2022国产成人精品无码区 | 亚洲人成电影网站| 亚洲导航深夜福利| 亚洲欧洲国产成人精品| 中文字幕在线观看亚洲| 亚洲国产综合专区电影在线| 亚洲国产精品第一区二区| 亚洲av日韩av无码黑人| 亚洲国产老鸭窝一区二区三区| 亚洲激情视频在线观看| 久久夜色精品国产噜噜亚洲AV| 久久久久亚洲精品无码蜜桃| 亚洲一区二区三区日本久久九| 久久亚洲私人国产精品vA | 亚洲AV无码XXX麻豆艾秋| 亚洲成a人片在线观看天堂无码| 亚洲AV无码之国产精品| 在线观看亚洲精品专区| 另类图片亚洲校园小说区| 亚洲乱码国产一区网址| 亚洲中文字幕无码专区| 国产亚洲精品福利在线无卡一| 亚洲日韩精品一区二区三区| 国产成人精品日本亚洲网站| 亚洲AV综合色区无码另类小说| 亚洲AV无码欧洲AV无码网站| 国产成人亚洲综合无码精品| 亚洲国产精品一区二区久久| 亚洲黄色免费网址| 亚洲专区中文字幕| 亚洲欧美第一成人网站7777| 全亚洲最新黄色特级网站 | 亚洲精品综合久久中文字幕| 精品久久亚洲中文无码| 亚洲伊人久久大香线蕉AV| 亚洲AV成人一区二区三区观看 | 国产精品亚洲综合网站|