自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

值得永久收藏的 C# 設(shè)計(jì)模式套路

開發(fā) 后端
關(guān)于設(shè)計(jì)模式的說法,網(wǎng)上一搜一大堆,咱就不再去說了。我的理解,設(shè)計(jì)模式就是很多NB的大佬們總結(jié)出來的,用來處理特定情況的標(biāo)準(zhǔn)解決方案。

[[434250]]

關(guān)于設(shè)計(jì)模式的說法,網(wǎng)上一搜一大堆,咱就不再去說了。

我的理解,設(shè)計(jì)模式就是很多NB的大佬們總結(jié)出來的,用來處理特定情況的標(biāo)準(zhǔn)解決方案。

那既然是標(biāo)準(zhǔn)方案,就一定會(huì)有套路,會(huì)有標(biāo)準(zhǔn)的樣子。

幾種常見的設(shè)計(jì)模式,都有各自的套路模板。下面進(jìn)入主題,咱們一個(gè)一個(gè)來說。

一、抽象工廠模式

抽象工廠主要的場(chǎng)景是創(chuàng)建一系列相關(guān)或相似的對(duì)象。注意這個(gè)相關(guān)或相似。因?yàn)橛羞@個(gè)特性,我們就可以抽取出共同點(diǎn),來形成接口或抽象類,然后通過這個(gè)接口或抽象類,來派生出各個(gè)對(duì)象。

為什么叫抽象工廠?不知道,而且不重要。在我看來,這只是個(gè)名字,記下就好。一個(gè)東西出來,總要有個(gè)名字的,有個(gè)人跑出來說,就叫抽象工廠吧。于是就叫抽象工廠了。就像一個(gè)人,做了一個(gè)網(wǎng)站,讓別人在上面賣東西,后來做大了,需要吹NB了,得給這個(gè)經(jīng)營方式起個(gè)名字,于是,B2C 就出現(xiàn)了?,F(xiàn)在人們創(chuàng)業(yè)做電商,頭一件事先討論做 B2B 還是 B2C。做反了。先做吧,掙錢要緊。做大了,你說叫什么,都會(huì)有人聽、有人信。

說跑題了,:P

?

先寫幾個(gè)類型,包括接口和實(shí)體類,后面會(huì)用到:

  1. // 接口定義 
  2. public interface ILaptop 
  3.     void GetInfo(); 
  4. public interface IMobile 
  5.     void GetInfo(); 
  6.  
  7. // 實(shí)體類一 
  8. public class MateBook : ILaptop 
  9.     public void GetInfo() 
  10.     { 
  11.         Console.WriteLine("I am MateBook"); 
  12.     } 
  13. public class Mac : ILaptop 
  14.     public void GetInfo() 
  15.     { 
  16.         Console.WriteLine("I am Mac"); 
  17.     } 
  18.  
  19. // 實(shí)體類二 
  20. public class Mate : IMobile 
  21.     public void GetInfo() 
  22.     { 
  23.         Console.WriteLine("I am Mate"); 
  24.     } 
  25. public class IPhone : IMobile 
  26.     public void GetInfo() 
  27.     { 
  28.         Console.WriteLine("I am IPhone"); 
  29.     } 

有了上面的類型,我們來看看抽象工廠的套路。

定義:

  1. public interface IFactory 
  2.     ILaptop CreateLaptop(); 
  3.     IMobile CreateMobile(); 
  4. public class FactoryA : IFactory 
  5.     public ILaptop CreateLaptop() 
  6.     { 
  7.         return new MateBook(); 
  8.     } 
  9.     public IMobile CreateMobile() 
  10.     { 
  11.         return new Mate(); 
  12.     } 
  13. public class FactoryB : IFactory 
  14.     public ILaptop CreateLaptop() 
  15.     { 
  16.         return new Mac(); 
  17.     } 
  18.     public IMobile CreateMobile() 
  19.     { 
  20.         return new IPhone(); 
  21.     } 

調(diào)用:

  1. public static class Example 
  2.     public static void ExampleTest() 
  3.     { 
  4.         var factoryA = new FactoryA(); 
  5.         var laptopA = factoryA.CreateLaptop(); 
  6.         var mobileA = factoryA.CreateMobile(); 
  7.         laptopA.GetName(); 
  8.         mobileA.GetName(); 
  9.  
  10.         var factoryB = new FactoryB(); 
  11.         var laptopB = factoryB.CreateLaptop(); 
  12.         var mobileB = factoryB.CreateMobile(); 
  13.         laptopB.GetName(); 
  14.         mobileB.GetName(); 
  15.     } 
  16.     //result : 
  17.     //I am MateBook 
  18.     //I am Mate 
  19.     //I am Mac 
  20.     //I am IPhone 

這個(gè)模式里面,核心的部分就是工廠接口的定義:

  1. public interface IFactory 
  2.     ILaptop CreateLaptop(); 
  3.     IMobile CreateMobile(); 

在這個(gè)工廠接口中,加入了多個(gè)相似的接口。于是,調(diào)用端可以很簡(jiǎn)單的以類似的方式去調(diào)用,而工廠實(shí)體中,對(duì)內(nèi)部引用的實(shí)體進(jìn)行區(qū)分。一個(gè)典型的場(chǎng)景是:一個(gè)程序,對(duì)著很多種數(shù)據(jù)庫。這樣的情況,可以在工廠實(shí)體中區(qū)分具體連接哪種數(shù)據(jù)庫,而內(nèi)部的引用實(shí)體,則各自對(duì)應(yīng)不同的數(shù)據(jù)庫。外部調(diào)用時(shí),只需要在初始化時(shí)確認(rèn)使用哪種數(shù)據(jù)庫,后面的 CRUD 操作,就直接使用就成,調(diào)用端不需要考慮數(shù)據(jù)庫的區(qū)別。事實(shí)上,這也是抽象工廠用的最多的場(chǎng)景。

二、工廠模式

去掉了抽象兩個(gè)字,居然還是一個(gè)模式,而且是一個(gè)不同的模式。這個(gè)名字起的夠混亂。

不過老實(shí)說,工廠模式跟抽象工廠模式很像,區(qū)別是:抽象工廠模式是在工廠模式的基礎(chǔ)上,又做了一層抽象。

看套路:

  1. public interface IFactory 
  2.     ILaptop CreateLaptop(); 
  3. public class FactoryA : IFactory 
  4.     public ILaptop CreateLaptop() 
  5.     { 
  6.         return new MateBook(); 
  7.     } 
  8. public class FactoryB : IFactory 
  9.     public ILaptop CreateLaptop() 
  10.     { 
  11.         return new Mac(); 
  12.     } 
  13. public static class Example 
  14.     public static void Test() 
  15.     { 
  16.         var factoryA = new FactoryA(); 
  17.         var laptopA = factoryA.CreateLaptop(); 
  18.         laptopA.GetName(); 
  19.  
  20.         var factoryB = new FactoryA(); 
  21.         var laptopB = factoryB.CreateLaptop(); 
  22.         laptopB.GetName(); 
  23.     } 
  24.     //result : 
  25.     //I am MateBook 
  26.     //I am Mac 

看到了吧,跟抽象工廠確實(shí)很相似。不過在使用上,工廠模式用得會(huì)更多。任何類都可以按工廠模式來寫。這個(gè)模式最大的作用,是把定義和實(shí)體做了分層。開發(fā)時(shí),可以一部分人去定義接口,而另一部分人去實(shí)現(xiàn)這個(gè)接口。而且,工作模式可以隨時(shí)擴(kuò)展為抽象工廠。比方一開始只是可能有多種數(shù)據(jù)庫,但具體是哪些數(shù)據(jù)庫還沒確定,就可以先按工廠模式寫,等數(shù)據(jù)庫定下來,隨時(shí)就很容易轉(zhuǎn)為抽象工廠了。

三、建造者模式

這個(gè)名稱起的更不知所云了,就因?yàn)橐粋€(gè) Builder?

其實(shí)他說的是這么個(gè)事。我們經(jīng)??吹竭@樣的代碼:

  1. var mobile = new MobileBuilder() 
  2.                 .WithBrand("Apple"
  3.                 .WithModel("13Pro"
  4.                 .WithMemory("512G"
  5.                 .Build(); 

看著是不是很洋氣?

來看看這個(gè)套路:

  1. // 這就是個(gè)數(shù)據(jù)模型 
  2. public class Mobile 
  3.     public string Brand { get; set; } 
  4.     public string Model { get; set; } 
  5.     public string Memory { get; set; } 
  6.  
  7. // 這才是 Builder 的定義 
  8. public class MobileBuilder 
  9.     private readonly Mobile _mobile = new Mobile(); 
  10.     public MobileBuilder WithBrand(string brand) 
  11.     { 
  12.         _mobile.Brand = brand; 
  13.         return this; 
  14.     } 
  15.     public MobileBuilder WithModel(string model) 
  16.     { 
  17.         _mobile.Model = model; 
  18.         return this; 
  19.     } 
  20.     public MobileBuilder WithMemory(string memory) 
  21.     { 
  22.         _mobile.Memory = memory; 
  23.         return this; 
  24.     } 
  25.     public Mobile Build() 
  26.     { 
  27.         return _mobile; 
  28.     } 

然后就可以這樣調(diào)用了:

  1. public static class Example 
  2.     public static void Test() 
  3.     { 
  4.         var mobile = new MobileBuilder() 
  5.                         .WithBrand("Apple"
  6.                         .WithModel("13Pro"
  7.                         .WithMemory("512G"
  8.                         .Build(); 
  9.         Console.WriteLine(mobile.ToJson()); 
  10.     } 
  11.     //result : 
  12.     //{"Brand":"Apple","Model":"13Pro","Memory":"512G"

個(gè)人而言,我很喜歡這個(gè)套路,沒有別的,就是洋氣,非常的洋氣。應(yīng)用場(chǎng)景也非常多,所有數(shù)據(jù)的 DTO,都可以么寫。

四、原型模式

這個(gè)模式聽著會(huì)有點(diǎn)陌生??催^一些文章,也把它歸為是創(chuàng)建型模式。實(shí)際上,我更傾向于把它看作是一種代碼結(jié)構(gòu),而不是模式。這種結(jié)構(gòu)最大的作用,是復(fù)制 - 通過復(fù)制一個(gè)存在的實(shí)例來創(chuàng)建新實(shí)例。

代碼是這樣的:

  1. public class MobilePackage 
  2.     public string Color { get; set; } 
  3.     public Mobile Mobile { get; set; } 
  4.  
  5.       // 下面才是模式代碼 
  6.     public MobilePackage ShallowCopy() 
  7.     { 
  8.         return (MobilePackage)this.MemberwiseClone(); 
  9.     } 
  10.     public MobilePackage DeepCopy() 
  11.     { 
  12.         var clone = (MobilePackage)this.MemberwiseClone(); 
  13.         clone.Color = new string(Color); 
  14.         clone.Mobile = new Mobile 
  15.         { 
  16.             Brand = new string(Mobile.Brand), 
  17.             Model = new string(Mobile.Model), 
  18.             Memory = new string(Mobile.Memory), 
  19.         }; 
  20.         return clone; 
  21.     } 

看看,其實(shí)就是一段復(fù)制代碼。

但是要注意,對(duì)于深拷貝和淺拷貝,涉及到指針和引用,如果你不熟悉,了解后再用??匆幌律厦娴慕Y(jié)果:

  1. public static class Example 
  2.     public static void Test() 
  3.     { 
  4.         var mobilePackage = new MobilePackage 
  5.         { 
  6.             Color = "White"
  7.             Mobile = new Mobile 
  8.             { 
  9.                     Brand = "Apple"
  10.                     Model = "13Pro"
  11.                     Memory = "512G"
  12.             } 
  13.         }; 
  14.  
  15.         var shallowCopied = mobilePackage.ShallowCopy(); 
  16.         var deepCopied = mobilePackage.DeepCopy(); 
  17.  
  18.         mobilePackage.Color = "Black"
  19.         mobilePackage.Mobile.Brand = "Huawei"
  20.         mobilePackage.Mobile.Model = "Mate"
  21.  
  22.         Console.WriteLine(mobilePackage.ToJson()); 
  23.         Console.WriteLine(shallowCopied.ToJson()); 
  24.         Console.WriteLine(deepCopied.ToJson()); 
  25.     } 
  26.  
  27.     //result: 
  28.     //{"Color":"Black","Mobile":{"Brand":"Huawei","Model":"Mate","Memory":"512G"}} 
  29.     //{"Color":"White","Mobile":{"Brand":"Huawei","Model":"Mate","Memory":"512G"}} 
  30.     //{"Color":"White","Mobile":{"Brand":"Apple","Model":"13Pro","Memory":"512G"}} 

結(jié)果和你理解的是不是一樣?如果不一樣,去研究一下值和引用的區(qū)別。另外,C# 10 里新出來的 Record,就是一個(gè)典型的原型模式的類型,也可以了解一下。

五、單例模式

單例模式也是一個(gè)用處非常大的模式,而且這個(gè)名字起得挺直白。

單例模式,簡(jiǎn)單點(diǎn)說就是不管你 new 多少回,實(shí)際應(yīng)用全局內(nèi)存中只會(huì)有一份實(shí)例。

套路代碼特別簡(jiǎn)單:

  1. public sealed class Singleton 
  2.     private static Singleton _instance; 
  3.     private static readonly object _locker = new object(); 
  4.  
  5.     private Singleton() 
  6.     { 
  7.     } 
  8.  
  9.     public static Singleton GetInstance() 
  10.     { 
  11.         if (_instance == null
  12.         { 
  13.             lock (_locker) 
  14.             { 
  15.                 if (_instance == null
  16.                 { 
  17.                     _instance = new Singleton(); 
  18.                 } 
  19.             } 
  20.         } 
  21.         return _instance; 
  22.     } 

這里有兩個(gè)注意點(diǎn):

類聲明用到 sealed 關(guān)鍵字,以確保這個(gè)類不會(huì)被派生。

類構(gòu)造函數(shù)用了 private,以確保這個(gè)類不會(huì)被 new。這本身與單例無關(guān),只是通過這種方式來表明這是一個(gè)單例??刂茊卫淖詈诵牡拇a,其實(shí)是下面的 GetInstance() 方法。

調(diào)用時(shí),就是下面一行代碼:

  1. Singleton singleton = Singleton.GetInstance(); 

就OK了。

設(shè)計(jì)模式有很多種,對(duì)應(yīng)的套路也有很多。其中,有一些是簡(jiǎn)單無腦的套路,像上面的單例,而另一些就會(huì)比較復(fù)雜。

不過,既然是套路,總是有固定的代碼或結(jié)構(gòu)可循的。

我這個(gè)主題,打算分幾篇來寫。這是第一篇。

 

最后做個(gè)小注解:套路雖簡(jiǎn)單,也要吃透了再用。而且,有時(shí)候簡(jiǎn)單的代碼就能很好地完成任務(wù),一定不要過度使用。

 

責(zé)任編輯:武曉燕 來源: 老王Plus
相關(guān)推薦

2021-12-01 09:23:13

C# 模式套路

2024-03-20 10:59:37

開源

2009-08-26 10:24:04

C# Observer

2009-09-02 16:23:27

C# Singleto

2009-04-29 09:06:18

C#設(shè)計(jì)模式Adapter

2024-07-22 08:09:28

C#模式架構(gòu)

2009-08-31 16:01:31

C#和設(shè)計(jì)模式

2024-07-31 10:41:16

C#設(shè)計(jì)模式

2013-02-26 10:55:47

C#適配器設(shè)計(jì)模式

2023-01-13 09:53:32

2009-08-04 09:22:26

C#工廠模式

2010-11-29 09:26:05

jQuery特效

2009-08-31 16:12:02

C#使用Singlet

2024-07-31 08:33:17

2019-04-22 15:00:05

CSS前端開發(fā)

2017-01-03 17:51:21

AndroidViewHolder工具類

2013-07-22 10:01:03

JavascriptWeb

2009-09-07 04:59:12

C#模式窗體

2009-08-11 13:59:41

迭代器模式C# Iterator

2009-08-26 16:26:37

C#迭代器模式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)