访谒者模式(Vistor Pattern)

时间:2021-12-11 08:28:31

标签:

原文:C#设计模式(22)——访谒者模式(Vistor Pattern)

一、引言

  在上一篇博文中分享了责任链模式,责任链模式主要应用在系统中的某些成果需要多个东西参预才华完成的场景。在这篇博文中,我将为大家分享我对访谒者模式的理解。

二、访谒者模式介绍 2.1 访谒者模式的界说

  访谒者模式是封装一些施加于某种数据布局之上的操纵。一旦这些操纵需要改削的话,接受这个操纵的数据布局则可以生存不乱。访谒者模式适用于数据布局相对不变的系统, 它把数据布局和感化于数据布局之上的操纵之间的耦合度降低,使得操纵调集可以相对*地转变。

  数据布局的每一个节点都可以接受一个访谒者的挪用,此节点向访谒者东西传入节点东西,而访谒者东西则反过来执行节点东西的操纵。这样的过程叫做“双重分拨”。节点挪用访谒者,将它本身传入,访谒者则将某算法针对此节点执行。

2.2 访谒者模式的布局图

  从上面描述可知,访谒者模式是用来封装某种数据布局中的要领。具体封装过程是:每个元素接受一个访谒者的挪用,每个元素的Accept要领接受访谒者东西作为参数传入,访谒者东西则反过来挪用元素东西的操纵。具体的访谒者模式布局图如下所示。

访谒者模式(Vistor Pattern)

  这里需要明确一点:访谒者模式中具体访谒者的数目和具体节点的数目没有任何关系。从访谒者的布局图可以看出,访谒者模式涉及以下几类角色。

抽象访谒者角色(Vistor):声明一个活多个访谒操纵,使得所有具体访谒者必需实现的接口。

具体访谒者角色(ConcreteVistor):实现抽象访谒者角色中所有声明的接口。

抽象节点角色(Element):声明一个接受操纵,接受一个访谒者东西作为参数。

具体节点角色(ConcreteElement):实现抽象元素所规定的接受操纵。

布局东西角色(ObjectStructure):节点的容器,可以包罗多个差别类或接口的容器。

2.3 访谒者模式的实现

  在讲诉访谒者模式的实现时,我想先不用访谒者模式的方法来实现某个场景。具体场景是——此刻我想遍历每个元素东西,然后挪用每个元素东西的Print要领来打印该元素东西的信息。如果此时不给与访谒者模式的话,实现这个场景再简单不过了,具体实现代码如下所示:

1 namespace DonotUsevistorPattern 2 { 3 // 抽象元素角色 4 public abstract class Element 5 { 6 public abstract void Print(); 7 } 8 9 // 具体元素A 10 public class ElementA : Element 11 { 12 public override void Print() 13 { 14 Console.WriteLine("我是元素A"); 15 } 16 } 17 18 // 具体元素B 19 public class ElementB : Element 20 { 21 public override void Print() 22 { 23 Console.WriteLine("我是元素B"); 24 } 25 } 26 27 // 东西布局 28 public class ObjectStructure 29 { 30 private ArrayList elements = new ArrayList(); 31 32 public ArrayList Elements 33 { 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 else 48 { 49 elements.Add(new ElementB()); 50 } 51 } 52 } 53 } 54 55 class Program 56 { 57 static void Main(string[] args) 58 { 59 ObjectStructure objectStructure = new ObjectStructure(); 60 // 遍历东西布局中的东西调集,访谒每个元素的Print要领打印元素信息 61 foreach (Element e in objectStructure.Elements) 62 { 63 e.Print(); 64 } 65 66 Console.Read(); 67 } 68 } 69 }