这个模式就比较复杂,首先从概念来说,就是将对象的操作外包给其他对象,也就是访问者,从而实现在不改变个元素的前提下定义作用于这些元素的新操作。

当一个基类可以被访问,并具有名为 acceptVisitor 的公共方法,改方法接受参数 Visitor,然后根据传递 Visitor 对象调用公共方法 visit。

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
interface  Visitor
{
public function visit($visitor);
}

class Element
{
protected Visitor $visitor;

public string $name;

public function __construct(string $name)
{
$this->name = $name;
}

public function getName(): string
{
return $this->name;
}


public function acceptVisitor(Visitor $visitor)
{
$visitor->visit($this);
}

}

class NameVisitor implements Visitor
{

public function visit($visitor)
{
echo $visitor->getName(), PHP_EOL;
}
}

$element = new Element('wu');
echo $element->getName(), PHP_EOL;
$element->acceptVisitor(new NameVisitor());

我们可以看到,通过调用 acceptVisitor 方法接收一个访问者,具体对象可以把访问者的getName 能力也扩展为自己能力。当然如果你需要多个扩展能力,你可以有多个访问者。而 acceptVisitor 方法调用访问者的visit 方法时,传入 $this 是为了能使用 Element 的属性和方法,使其感觉扩展完就是 Element 的真正一部分。