日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

值得永久收藏的 C# 设计模式套路(二)

發(fā)布時間:2023/12/4 C# 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 值得永久收藏的 C# 设计模式套路(二) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

設計模式套路,第二彈。

在第一篇中,主要寫了創(chuàng)造模式相關的幾種套路。如果你是剛看到這個文章,建議你先去看看第一篇?傳送門。

這一篇,我們說說結(jié)構(gòu)模式相關的套路。

結(jié)構(gòu)模式,主要作用是將類型、對象和其它內(nèi)容放在一起,以創(chuàng)建更大的結(jié)構(gòu),同時,又可以保持高度的靈活性和最佳性能。

也是像上一篇一樣,一個一個來說。

一、適配器模式

適配器這個名字非常好理解,就像我們充電器的插頭,是用來協(xié)調(diào)兩個不同的東東之間的通信,并讓他們互相理解。

代碼也很簡單:

public?class?AnotherType {public?string?GetAuthorInfo(){return?"I?am?WangPlus";} } public?interface?IAdapter {string?GetInfo(); } public?class?Adapter?:?IAdapter {private?readonly?AnotherType?_anotherType;public?Adapter(AnotherType?anotherType){_anotherType?=?anotherType;}public?string?GetInfo(){return?_anotherType.GetAuthorInfo();} } public?class?Example {public?void?Test(){var?adapter?=?new?Adapter(new?AnotherType());Console.WriteLine(adapter.GetInfo());}//?result://?I?am?WangPlus }

沒想到吧?這樣的代碼經(jīng)常寫,居然也是個模式。所以呀,還是我上一篇提到的說法:先有內(nèi)容,然后才有概念和標準。套路一直在,只是很多人不知道他叫什么。

二、橋模式

這個也好理解,就是在兩個東西之間搭了一個橋。

正常使用時,是把實體類與接口和抽象分離開。有一個非常明顯的好處,是幾個實現(xiàn)可以使用不同的技術。

理解概念有點難,還是看代碼:

public?interface?IBridgeType {void?GetInfo(); } public?class?BridgeA?:?IBridgeType {public?void?GetInfo(){Console.WriteLine("I?am?WangPlus");} } public?class?BridgeB?:?IBridgeType {public?void?GetInfo(){Console.WriteLine("I?am?another?WangPlus");} } public?interface?IBridge {public?IBridgeType?bridgeType{get;set;}void?GetInfo(); } public?class?BridgeType?:?IBridge {public?IBridgeType?bridgeType{get;set;}public?void?GetInfo(){bridgeType.GetInfo();} } public?static?class?BridgeExample {public?static?void?Test(){var?bridgeType?=?new?BridgeType();bridgeType.bridgeType?=?new?BridgeA();bridgeType.GetInfo();bridgeType.bridgeType?=?new?BridgeB();bridgeType.GetInfo();}//?result://?I?am?WangPlus//?I?am?another?WangPlus }

BridgeA 和 BridgeA 是兩個實現(xiàn),這兒就是上面說的不同的技術,用不同的技術實現(xiàn)了同一個接口。然后通過 IBridge 橋接到一個實現(xiàn)中。

使用時,使用不同的實現(xiàn),但用相同的結(jié)構(gòu)進行調(diào)用。在有需要時,我們可以根據(jù)場景做出無數(shù)個 BridgeN ,來實現(xiàn)黑盒類似但白盒完全不同的實體。

三、復合模式

聽著就大就復雜。沒錯,所有叫復合的東西,都會形成一個樹狀結(jié)構(gòu)。這好像是編程中的一個默認約定?

復合設計模式,就是把對象放在一個更大的樹狀結(jié)構(gòu)的對象中,以多層次結(jié)構(gòu)來呈現(xiàn)對象,以統(tǒng)一方式處理對象。

看看這個復雜代碼的套路:

public?abstract?class?Mobile {protected?string?Name;protected?Mobile(string?name){Name?=?name;}public?virtual?void?Add(Mobile?mobile){throw?new?NotImplementedException();}public?virtual?void?GetTree(int?indent){throw?new?NotImplementedException();} } public?class?MobileMemory?:?Mobile {public?MobileMemory(string?name)?:?base(name)?{?}public?override?void?GetTree(int?indent){Console.WriteLine(new?String('-',?indent)?+?"?"?+?Name);} } public?class?MobileModel?:?Mobile {private?readonly?List<Mobile>?_mobiles?=?new?List<Mobile>();public?MobileModel(string?name)?:?base(name)?{?}public?override?void?Add(Mobile?mobile){_mobiles.Add(mobile);}public?override?void?GetTree(int?indent){Console.WriteLine(new?String('-',?indent)?+?"+?"?+?Name);foreach?(var?mobile?in?_mobiles){mobile.GetTree(indent?+?2);}} } public?static?class?Example {public?static?void?Test(){var?brand?=?new?MobileModel("IPhone");var?model13?=?new?MobileModel("13Pro");var?model12?=?new?MobileModel("12Pro");var?memory512G?=?new?MobileMemory("512G");var?memory256G?=?new?MobileMemory("256G");model13.Add(memory256G);model13.Add(memory512G);model12.Add(memory256G);model12.Add(memory512G);brand.Add(model12);brand.Add(model13);brand.GetTree(1);}//?result://?---+?12Pro//?-----?256G//?-----?512G//?---+?13Pro//?-----?256G//?-----?512G }

這個套路確實稍微有點復雜。補充解釋一下:

  • MobileMemory 和 MobileModel,是為了表現(xiàn)多種對象,沒有特殊含義,里面的區(qū)別就是 GetTree() 里打印出來的字符不同。

  • 需要清楚理解的部分是 MobileModel 里構(gòu)建的 _mobiles,他是一個頂層抽象類的數(shù)組。

  • 這個模式最重要的結(jié)構(gòu),是用抽象類去組織數(shù)據(jù),用實體類去操作功能。

另外,如果你的開發(fā)功力夠,在這個架構(gòu)中,實體本身也可以是復合對象。

四、裝飾模式

這也是一個常用的模式。通過對抽象或接口的擴展,來加入對象功能。

而且這個套路的代碼特別好理解:

public?interface?IMobile {public?string?Brand{get;}public?string?Model{get;}public?abstract?void?GetInfo(); } public?class?IPhone?:?IMobile {public?string?Brand?=>?"Apple";public?string?Model?=>?"13Pro";public?void?GetInfo(){Console.WriteLine(this.ToJson());} } public?class?IPhoneWithMemory?:?IMobile {private?readonly?IMobile?_mobile;public?IPhoneWithMemory(IMobile?mobile){_mobile?=?mobile;}public?string?Brand?=>?"Apple";public?string?Model?=>?"13Pro";public?string?Memory?=>?"512G";public?void?GetInfo(){Console.WriteLine(this.ToJson());} } public?static?class?Example {public?static?void?Test(){var?iphone?=?new?IPhone();iphone.GetInfo();var?iphoneWithMemory?=?new?IPhoneWithMemory(iphone);iphoneWithMemory.GetInfo();}//?result://?{"Brand":"Apple","Model":"13Pro"}//?{"Brand":"Apple","Model":"13Pro","Memory":"512G"} }

從上邊的 IMobile 接口開始,每一個實體都是對前一個實體的補充和完善。

這種寫法,在團隊項目中很常見,可以在確保不對別人的內(nèi)容進行修改的基礎上,擴展新的功能。不用改別人的代碼,又能補充進去新的內(nèi)容。有沒有被爽到?

五、外觀模式

這個模式名稱起得不知所云。不過意思和代碼倒是很簡單,就是把其它的接口、類、框架等的復雜系統(tǒng)匯集起來,讓人能簡單使用。

代碼一看就懂:

public?class?Facade {private?readonly?Mobile?_mobile;private?readonly?Laptop?_laptop;public?Facade(Mobile?mobile,?Laptop?laptop){_mobile?=?mobile;_laptop?=?laptop;}public?void?GetInfo(){_mobile.GetInfo();_laptop.GetInfo();} } public?class?Mobile {public?void?GetInfo(){Console.WriteLine("I?am?mobile");} } public?class?Laptop {public?void?GetInfo(){Console.WriteLine("I?am?laptop");} } public?static?class?Example {public?static?void?Test(){var?mobile?=?new?Mobile();var?laptop?=?new?Laptop();var?facade?=?new?Facade(mobile,?laptop);facade.GetInfo();}//?result://?I?am?mobile//?I?am?laptop }

這個模式,在開發(fā)中也用得比較多。尤其在團隊項目中,會經(jīng)常用到,原因跟上面一樣。

六、輕量級模式

嗯,就是輕的意思。這個輕,不是寫的少,而是內(nèi)存使用少。

所以這個模式的主要優(yōu)勢,就是節(jié)省內(nèi)存。

這個模式?jīng)]辦法給出簡單的套路。他本身是一種想法,是一種寫在代碼中的思想,而不是一個套路性的代碼組。

我拿一段代碼來說明一下:

public?class?Flyweight {private?readonly?List<KeyValuePair<string,?DemoClass>>?_sharedObjects?=?new();public?Flyweight(){_sharedObjects.Add(new?KeyValuePair<string,?DemoClass>("A",?new?DemoClass()));_sharedObjects.Add(new?KeyValuePair<string,?DemoClass>("B",?new?DemoClass()));}public?DemoClass?GetObject(string?key){return?_sharedObjects.SingleOrDefault(c?=>?c.Key?==?key).Value;} } public?interface?IDemoClass {public?void?Operation(string?name); } public?class?DemoClass?:?IDemoClass {public?void?Operation(string?name){Console.WriteLine(name);} } public?static?class?Example {public?static?void?Test(){var?flyweight?=?new?Flyweight();flyweight.GetObject("A").Operation("Hello");flyweight.GetObject("B").Operation("I?am?WangPlus");var?heavy?=?new?DemoClass();heavy.Operation("Hello,?I?am?WangPlus");}//?result://?下面是輕量級模式//?Hello//?I?am?WangPlus//?下面是普通模式//?Hello,?I?am?WangPlus }

在這段代碼里,真正屬于輕量級模式模式的其實只是里面的這一段:

private?readonly?List<KeyValuePair<string,?DemoClass>>?_sharedObjects?=?new();public?Flyweight(){_sharedObjects.Add(new?KeyValuePair<string,?DemoClass>("A",?new?DemoClass()));_sharedObjects.Add(new?KeyValuePair<string,?DemoClass>("B",?new?DemoClass()));}

能理解嗎?這一段主要是構(gòu)造了一個集合,用來存放對象。后面調(diào)用對象時,是從這個集合里出來的。

這樣寫的好處,是如果對象很多,每次 new 會占用大量內(nèi)存,而先期存儲在一個集合中,會讓這個內(nèi)存占用變得小很多。

好吧,如果不理解,也沒關系。在 Dotnet 的整個源碼中,這樣使用的也并不多。

所以這個模式屬于一個可以意會的模式。而且事實上,現(xiàn)在的內(nèi)存成本之低,已經(jīng)很少需要這么費心了。

七、代理模式

這個模式也好理解,就是加了一個代理。通過中間類型來控制對于主類型的訪問。

嗯,別擔心,這個是有套路的。

public?abstract?class?MainAbst {public?abstract?void?GetInfo(); } public?class?MainClass?:?MainAbst {public?override?void?GetInfo(){Console.WriteLine("I?am?WangPlus");} } public?class?Proxy?:?MainAbst {private?MainClass?_main;public?Proxy(MainClass?main){_main?=?main;}public?override?void?GetInfo(){_main????=?new?MainClass();_main.GetInfo();} } public?static?class?ProxyExample {public?static?void?Test(){var?proxy?=?new?Proxy(new?MainClass());proxy.GetInfo();}//?result://?I?am?WangPlus }

這個套路也容易懂。MainClass 是我們的主類,在執(zhí)行一些特定的方法。加出了一個代理類 Proxy。外部調(diào)用時,通過 Proxy 來調(diào)用主類的方法,同時,如果有需要對主類的輸入輸出進行處理,可以在 Proxy 的方法里直接寫。

又是一個團隊協(xié)作會用到的模式,嘿嘿。

結(jié)構(gòu)模式的套路就是這樣了。

還有一類模式,是行為設計模式。咱們改天再寫。

喜歡就來個三連,讓更多人因你而受益

總結(jié)

以上是生活随笔為你收集整理的值得永久收藏的 C# 设计模式套路(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。