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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

java的string访问某个元素_C#深究.net常用的23种设计模式之访问者模式(Vistor Pattern)...

發(fā)布時(shí)間:2023/12/2 C# 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java的string访问某个元素_C#深究.net常用的23种设计模式之访问者模式(Vistor Pattern)... 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、引言

  在上一篇博文中分享了責(zé)任鏈模式,責(zé)任鏈模式主要應(yīng)用在系統(tǒng)中的某些功能需要多個(gè)對象參與才能完成的場景。在這篇博文中,我將為大家分享我對訪問者模式的理解。

二、訪問者模式介紹

2.1 訪問者模式的定義

?  訪問者模式是封裝一些施加于某種數(shù)據(jù)結(jié)構(gòu)之上的操作。一旦這些操作需要修改的話,接受這個(gè)操作的數(shù)據(jù)結(jié)構(gòu)則可以保存不變。訪問者模式適用于數(shù)據(jù)結(jié)構(gòu)相對穩(wěn)定的系統(tǒng), 它把數(shù)據(jù)結(jié)構(gòu)和作用于數(shù)據(jù)結(jié)構(gòu)之上的操作之間的耦合度降低,使得操作集合可以相對自由地改變。

  數(shù)據(jù)結(jié)構(gòu)的每一個(gè)節(jié)點(diǎn)都可以接受一個(gè)訪問者的調(diào)用,此節(jié)點(diǎn)向訪問者對象傳入節(jié)點(diǎn)對象,而訪問者對象則反過來執(zhí)行節(jié)點(diǎn)對象的操作。這樣的過程叫做“雙重分派”。節(jié)點(diǎn)調(diào)用訪問者,將它自己傳入,訪問者則將某算法針對此節(jié)點(diǎn)執(zhí)行。

2.2 訪問者模式的結(jié)構(gòu)圖

?  從上面描述可知,訪問者模式是用來封裝某種數(shù)據(jù)結(jié)構(gòu)中的方法。具體封裝過程是:每個(gè)元素接受一個(gè)訪問者的調(diào)用,每個(gè)元素的Accept方法接受訪問者對象作為參數(shù)傳入,訪問者對象則反過來調(diào)用元素對象的操作。具體的訪問者模式結(jié)構(gòu)圖如下所示。

  這里需要明確一點(diǎn):訪問者模式中具體訪問者的數(shù)目和具體節(jié)點(diǎn)的數(shù)目沒有任何關(guān)系。從訪問者的結(jié)構(gòu)圖可以看出,訪問者模式涉及以下幾類角色。

  • 抽象訪問者角色(Vistor):聲明一個(gè)活多個(gè)訪問操作,使得所有具體訪問者必須實(shí)現(xiàn)的接口。

  • 具體訪問者角色(ConcreteVistor):實(shí)現(xiàn)抽象訪問者角色中所有聲明的接口。

  • 抽象節(jié)點(diǎn)角色(Element):聲明一個(gè)接受操作,接受一個(gè)訪問者對象作為參數(shù)。

  • 具體節(jié)點(diǎn)角色(ConcreteElement):實(shí)現(xiàn)抽象元素所規(guī)定的接受操作。

  • 結(jié)構(gòu)對象角色(ObjectStructure):節(jié)點(diǎn)的容器,可以包含多個(gè)不同類或接口的容器。

2.3 訪問者模式的實(shí)現(xiàn)

?  在講訴訪問者模式的實(shí)現(xiàn)時(shí),我想先不用訪問者模式的方式來實(shí)現(xiàn)某個(gè)場景。具體場景是——現(xiàn)在我想遍歷每個(gè)元素對象,然后調(diào)用每個(gè)元素對象的Print方法來打印該元素對象的信息。如果此時(shí)不采用訪問者模式的話,實(shí)現(xiàn)這個(gè)場景再簡單不過了,具體實(shí)現(xiàn)代碼如下所示:

1 namespace DonotUsevistorPattern 2 { 3 // 抽象元素角色 4 public abstract class Element 5 { 6 public abstract void Print(); 7 } 8 9 // 具體元素A10 public class ElementA : Element11 { 12 public override void Print()13 {14 Console.WriteLine("我是元素A");15 }16 }17 18 // 具體元素B19 public class ElementB : Element20 {21 public override void Print()22 {23 Console.WriteLine("我是元素B");24 }25 }26 27 // 對象結(jié)構(gòu)28 public class ObjectStructure29 {30 private ArrayList elements = new ArrayList();31 32 public ArrayList Elements33 {34 get { return elements; }35 }36 37 public ObjectStructure()38 {39 Random ran = new Random();40 for (int i = 0; i < 6; i++)41 {42 int ranNum = ran.Next(10);43 if (ranNum > 5)44 {45 elements.Add(new ElementA());46 }47 else48 {49 elements.Add(new ElementB());50 }51 }52 }53 }54 55 class Program56 {57 static void Main(string[] args)58 {59 ObjectStructure objectStructure = new ObjectStructure();60 // 遍歷對象結(jié)構(gòu)中的對象集合,訪問每個(gè)元素的Print方法打印元素信息61 foreach (Element e in objectStructure.Elements)62 {63 e.Print();64 }65 66 Console.Read();67 }68 }69 }

  上面代碼很準(zhǔn)確了解決了我們剛才提出的場景,但是需求在時(shí)刻變化的,如果此時(shí),我除了想打印元素的信息外,還想打印出元素被訪問的時(shí)間,此時(shí)我們就不得不去修改每個(gè)元素的Print方法,再加入相對應(yīng)的輸入訪問時(shí)間的輸出信息。這樣的設(shè)計(jì)顯然不符合“開-閉”原則,即某個(gè)方法操作的改變,會(huì)使得必須去更改每個(gè)元素類。既然,這里變化的點(diǎn)是操作的改變,而每個(gè)元素的數(shù)據(jù)結(jié)構(gòu)是不變的。所以此時(shí)就思考——能不能把操作于元素的操作和元素本身的數(shù)據(jù)結(jié)構(gòu)分開呢?解開這兩者的耦合度,這樣如果是操作發(fā)現(xiàn)變化時(shí),就不需要去更改元素本身了,但是如果是元素?cái)?shù)據(jù)結(jié)構(gòu)發(fā)現(xiàn)變化,例如,添加了某個(gè)字段,這樣就不得不去修改元素類了。此時(shí),我們可以使用訪問者模式來解決這個(gè)問題,即把作用于具體元素的操作由訪問者對象來調(diào)用。具體的實(shí)現(xiàn)代碼如下所示:

1 namespace VistorPattern 2 { 3 // 抽象元素角色 4 public abstract class Element 5 { 6 public abstract void Accept(IVistor vistor); 7 public abstract void Print(); 8 } 9 10 // 具體元素A 11 public class ElementA :Element 12 { 13 public override void Accept(IVistor vistor) 14 { 15 // 調(diào)用訪問者visit方法 16 vistor.Visit(this); 17 } 18 public override void Print() 19 { 20 Console.WriteLine("我是元素A"); 21 } 22 } 23 24 // 具體元素B 25 public class ElementB :Element 26 { 27 public override void Accept(IVistor vistor) 28 { 29 vistor.Visit(this); 30 } 31 public override void Print() 32 { 33 Console.WriteLine("我是元素B"); 34 } 35 } 36 37 // 抽象訪問者 38 public interface IVistor 39 { 40 void Visit(ElementA a); 41 void Visit(ElementB b); 42 } 43 44 // 具體訪問者 45 public class ConcreteVistor :IVistor 46 { 47 // visit方法而是再去調(diào)用元素的Accept方法 48 public void Visit(ElementA a) 49 { 50 a.Print(); 51 } 52 public void Visit(ElementB b) 53 { 54 b.Print(); 55 } 56 } 57 58 // 對象結(jié)構(gòu) 59 public class ObjectStructure 60 { 61 private ArrayList elements = new ArrayList(); 62 63 public ArrayList Elements 64 { 65 get { return elements; } 66 } 67 68 public ObjectStructure() 69 { 70 Random ran = new Random(); 71 for (int i = 0; i < 6; i++) 72 { 73 int ranNum = ran.Next(10); 74 if (ranNum > 5) 75 { 76 elements.Add(new ElementA()); 77 } 78 else 79 { 80 elements.Add(new ElementB()); 81 } 82 } 83 } 84 } 85 86 class Program 87 { 88 static void Main(string[] args) 89 { 90 ObjectStructure objectStructure = new ObjectStructure(); 91 foreach (Element e in objectStructure.Elements) 92 { 93 // 每個(gè)元素接受訪問者訪問 94 e.Accept(new ConcreteVistor()); 95 } 96 97 Console.Read(); 98 } 99 }100 }

  從上面代碼可知,使用訪問者模式實(shí)現(xiàn)上面場景后,元素Print方法的訪問封裝到了訪問者對象中了(我覺得可以把Print方法封裝到具體訪問者對象中。),此時(shí)客戶端與元素的Print方法就隔離開了。此時(shí),如果需要添加打印訪問時(shí)間的需求時(shí),此時(shí)只需要再添加一個(gè)具體的訪問者類即可。此時(shí)就不需要去修改元素中的Print()方法了。

三、訪問者模式的應(yīng)用場景

?  每個(gè)設(shè)計(jì)模式都有其應(yīng)當(dāng)使用的情況,那讓我們看看訪問者模式具體應(yīng)用場景。如果遇到以下場景,此時(shí)我們可以考慮使用訪問者模式。

  • 如果系統(tǒng)有比較穩(wěn)定的數(shù)據(jù)結(jié)構(gòu),而又有易于變化的算法時(shí),此時(shí)可以考慮使用訪問者模式。因?yàn)樵L問者模式使得算法操作的添加比較容易。

  • 如果一組類中,存在著相似的操作,為了避免出現(xiàn)大量重復(fù)的代碼,可以考慮把重復(fù)的操作封裝到訪問者中。(當(dāng)然也可以考慮使用抽象類了)

  • 如果一個(gè)對象存在著一些與本身對象不相干,或關(guān)系比較弱的操作時(shí),為了避免操作污染這個(gè)對象,則可以考慮把這些操作封裝到訪問者對象中。

四、訪問者模式的優(yōu)缺點(diǎn)?

?  訪問者模式具有以下優(yōu)點(diǎn):

  • 訪問者模式使得添加新的操作變得容易。如果一些操作依賴于一個(gè)復(fù)雜的結(jié)構(gòu)對象的話,那么一般而言,添加新的操作會(huì)變得很復(fù)雜。而使用訪問者模式,增加新的操作就意味著添加一個(gè)新的訪問者類。因此,使得添加新的操作變得容易。

  • 訪問者模式使得有關(guān)的行為操作集中到一個(gè)訪問者對象中,而不是分散到一個(gè)個(gè)的元素類中。這點(diǎn)類似與"中介者模式"。

  • 訪問者模式可以訪問屬于不同的等級(jí)結(jié)構(gòu)的成員對象,而迭代只能訪問屬于同一個(gè)等級(jí)結(jié)構(gòu)的成員對象。

  訪問者模式也有如下的缺點(diǎn):

  • 增加新的元素類變得困難。每增加一個(gè)新的元素意味著要在抽象訪問者角色中增加一個(gè)新的抽象操作,并在每一個(gè)具體訪問者類中添加相應(yīng)的具體操作。

五、總結(jié)

  訪問者模式是用來封裝一些施加于某種數(shù)據(jù)結(jié)構(gòu)之上的操作。它使得可以在不改變元素本身的前提下增加作用于這些元素的新操作,訪問者模式的目的是把操作從數(shù)據(jù)結(jié)構(gòu)中分離出來。

總結(jié)

以上是生活随笔為你收集整理的java的string访问某个元素_C#深究.net常用的23种设计模式之访问者模式(Vistor Pattern)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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