设计模式 <行为型> | 访问者模式

访问者模式(Visitor Pattern)

访问者模式就是将对象和对象本身的动作解耦,让操作可以独自变化。

结构图:

角色

  1. 抽象访问者(Visitor):为每一个具体元素类声明一个具体访问者的操作。
  2. 具体访问者(Concrete Visitor):实现抽象访问者中的操作。可以有多个实现。
  3. 抽象元素(Element):接口申明一个 accept 方法表示接受访问者的访问。该方法必须有一个参数被声明为访问者接口类型。
  4. 具体元素(Concrete Element):实现接收方法。根据当前元素类将其调用重定向到相应访问者的方法。

适用场景:

  1. 对一个复杂对象结构譬如树中的所有元素执行某些操作,可使用访问者模式。

优点:

  1. 可以引入在不同类对象上执行的新行为,且无需对这些类做出修改,符合开闭原则
  2. 可以将同一行为的不同版本移到同一个类中。符合单一原则。

缺点:

  1. 增加修改元素需要修改所有的访问者。

代码(C#)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/// <summary>
/// 抽象元素
/// </summary>
interface IComponent
{
void Accept(IVisitor visitor);
}

/// <summary>
/// 具体元素
/// </summary>
class ConcreteComponentA : IComponent
{
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}

public string ShowA()
{
return "A";
}
}

/// <summary>
/// 具体元素
/// </summary>
class ConcreteComponentB : IComponent
{
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}

public string ShowB()
{
return "B";
}
}

/// <summary>
/// 抽象访问者
/// </summary>
interface IVisitor
{
void Visit(ConcreteComponentA component);
void Visit(ConcreteComponentB component);
}

/// <summary>
/// 具体访问者
/// </summary>
class ConcreteVisitorA : IVisitor
{
public void Visit(ConcreteComponentA component)
{
Console.WriteLine($"ConcreteVisitorA + {component.ShowA()}");
}


public void Visit(ConcreteComponentB component)
{
Console.WriteLine($"ConcreteVisitorA + {component.ShowB()}");
}
}


/// <summary>
/// 具体访问者
/// </summary>
class ConcreteVisitorB : IVisitor
{
public void Visit(ConcreteComponentA component)
{
Console.WriteLine($"ConcreteVisitorB + {component.ShowA()}");
}


public void Visit(ConcreteComponentB component)
{
Console.WriteLine($"ConcreteVisitorB + {component.ShowB()}");
}
}

List<IComponent> components = new List<IComponent>
{
new ConcreteComponentA(),
new ConcreteComponentB()
};
IVisitor visitor1 = new ConcreteVisitorA();
foreach (var item in components)
{
item.Accept(visitor1);
}

最后

访问者模式函数重载在大部分是静态绑定的。也就是说,调用类的哪个重载函数,是在编译期间,由参数的声明类型决定的,而非运行时,根据参数的实际类型决定的。


设计模式 <行为型> | 访问者模式
http://example.com/posts/57589.html
作者
她微笑的脸y
发布于
2023年3月13日
许可协议