<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 8362字,需瀏覽 17分鐘

           ·

          2022-01-02 12:03

          設(shè)計(jì)模式套路,第二彈。

          ?

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

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

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

          也是像上一篇一樣,一個(gè)一個(gè)來(lái)說(shuō)。

          一、適配器模式

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

          代碼也很簡(jiǎn)單:

          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
          }

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

          二、橋模式

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

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

          理解概念有點(diǎ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 是兩個(gè)實(shí)現(xiàn),這兒就是上面說(shuō)的不同的技術(shù),用不同的技術(shù)實(shí)現(xiàn)了同一個(gè)接口。然后通過(guò) IBridge 橋接到一個(gè)實(shí)現(xiàn)中。

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

          三、復(fù)合模式

          聽(tīng)著就大就復(fù)雜。沒(méi)錯(cuò),所有叫復(fù)合的東西,都會(huì)形成一個(gè)樹(shù)狀結(jié)構(gòu)。這好像是編程中的一個(gè)默認(rèn)約定?

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

          看看這個(gè)復(fù)雜代碼的套路:

          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?_mobiles?=?new?List();
          ????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
          }

          這個(gè)套路確實(shí)稍微有點(diǎn)復(fù)雜。補(bǔ)充解釋一下:

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

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

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

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

          四、裝飾模式

          這也是一個(gè)常用的模式。通過(guò)對(duì)抽象或接口的擴(kuò)展,來(lái)加入對(duì)象功能。

          而且這個(gè)套路的代碼特別好理解:

          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 接口開(kāi)始,每一個(gè)實(shí)體都是對(duì)前一個(gè)實(shí)體的補(bǔ)充和完善。

          這種寫(xiě)法,在團(tuán)隊(duì)項(xiàng)目中很常見(jiàn),可以在確保不對(duì)別人的內(nèi)容進(jìn)行修改的基礎(chǔ)上,擴(kuò)展新的功能。不用改別人的代碼,又能補(bǔ)充進(jìn)去新的內(nèi)容。有沒(méi)有被爽到?

          五、外觀(guān)模式

          這個(gè)模式名稱(chēng)起得不知所云。不過(guò)意思和代碼倒是很簡(jiǎn)單,就是把其它的接口、類(lèi)、框架等的復(fù)雜系統(tǒng)匯集起來(lái),讓人能簡(jiǎn)單使用。

          代碼一看就懂:

          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
          }

          這個(gè)模式,在開(kāi)發(fā)中也用得比較多。尤其在團(tuán)隊(duì)項(xiàng)目中,會(huì)經(jīng)常用到,原因跟上面一樣。

          六、輕量級(jí)模式

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

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

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

          我拿一段代碼來(lái)說(shuō)明一下:

          public?class?Flyweight
          {

          ????private?readonly?Liststring,?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:
          ????//?下面是輕量級(jí)模式
          ????//?Hello
          ????//?I?am?WangPlus
          ????//?下面是普通模式
          ????//?Hello,?I?am?WangPlus
          }

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

          ????private?readonly?Liststring,?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)造了一個(gè)集合,用來(lái)存放對(duì)象。后面調(diào)用對(duì)象時(shí),是從這個(gè)集合里出來(lái)的。

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

          好吧,如果不理解,也沒(méi)關(guān)系。在 Dotnet 的整個(gè)源碼中,這樣使用的也并不多。

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

          七、代理模式

          這個(gè)模式也好理解,就是加了一個(gè)代理。通過(guò)中間類(lèi)型來(lái)控制對(duì)于主類(lèi)型的訪(fǎng)問(wèn)。

          嗯,別擔(dān)心,這個(gè)是有套路的。

          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
          }

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

          又是一個(gè)團(tuán)隊(duì)協(xié)作會(huì)用到的模式,嘿嘿。

          ?

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

          還有一類(lèi)模式,是行為設(shè)計(jì)模式。咱們改天再寫(xiě)。

          喜歡就來(lái)個(gè)三連,讓更多人因你而受益


          瀏覽 46
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色777777AV | 成人免费看性爱大片密芽 | 日韩国产毛片一区二区三区无码精品 | 国产精品第一页在线观看 | 99思思视频 |