1 <?php
2
3 /**
4 * 和观察者模式有一丝相似
5 */
6
7 /**
8 * 抽象访问者角色, 要定义好针对所有元素的处理操作
9 */
10 interface Visitor {
11 public function visitConcreteElementA(ConcreteElementA $elementA);
12 public function visitConcreteElementB(concreteElementB $elementB);
13 }
14
15 /**
16 * 抽象元素角色
17 */
18 interface Element {
19 public function accept(Visitor $visitor);
20 }
21
22
23
24
25
26 /**
27 * 具体的访问者1
28 */
29 class ConcreteVisitor1 implements Visitor {
30 private $_name;
31
32 public function __construct($name)
33 {
34 $this->_name = $name;
35 }
36
37 public function visitConcreteElementA(ConcreteElementA $elementA)
38 {
39 echo "<br/>", "哈哈, 小妞({$elementA->getName()}), 给本大爷({$this->_name})笑一个";
40 }
41
42 public function visitConcreteElementB(ConcreteElementB $elementB)
43 {
44 echo "<br/>", "哈哈, 小妞({$elementB->getName()}), 给本大爷({$this->_name})笑一个";
45 }
46 }
47
48 /**
49 * 具体的访问者2
50 */
51 class ConcreteVisitor2 implements Visitor {
52 private $_name;
53
54 public function __construct($name)
55 {
56 $this->_name = $name;
57 }
58
59 public function visitConcreteElementA(ConcreteElementA $elementA)
60 {
61 echo "<br/>", "哈哈, 小妞({$elementA->getName()}), 给本大爷({$this->_name})笑一个";
62 }
63
64 public function visitConcreteElementB(ConcreteElementB $elementB)
65 {
66 echo "<br/>", "哈哈, 小妞({$elementB->getName()}), 给本大爷({$this->_name})笑一个";
67 }
68 }
69
70
71
72
73
74 /**
75 * 具体元素A
76 */
77 class ConcreteElementA implements Element {
78 private $_name;
79
80 public function __construct($name)
81 {
82 $this->_name = $name;
83 }
84
85 public function getName()
86 {
87 return $this->_name;
88 }
89
90 /**
91 * @param Visitor $visitor 接受访问者调用它针对该元素的新方法
92 */
93 public function accept(Visitor $visitor)
94 {
95 $visitor->visitConcreteElementA($this);
96 }
97 }
98
99 /**
100 * 具体元素B
101 */
102 class ConcreteElementB implements Element {
103 private $_name;
104
105 public function __construct($name)
106 {
107 $this->_name = $name;
108 }
109
110 public function getName()
111 {
112 return $this->_name;
113 }
114
115 /**
116 * @param Visitor $visitor 接受访问者调用它针对该元素的新方法
117 */
118 public function accept(Visitor $visitor)
119 {
120 $visitor->visitConcreteElementB($this);
121 }
122 }
123
124
125
126
127 /**
128 * 对象结构 即元素的集合
129 */
130 class ObjectStructure {
131 private $_collection; //具体的元素的集合
132
133 public function __construct()
134 {
135 $this->_collection = [];
136 }
137
138 public function attach(Element $element) {
139 return array_push($this->_collection, $element);
140 }
141
142 public function detach(Element $element) {
143 $index = array_search($element, $this->_collection);
144
145 if ($index !== FALSE) {
146 unset($this->_collection[$index]);
147 }
148 return $index;
149 }
150
151 /**
152 * 访问者可以访问这些元素集合
153 *
154 * @param Visitor $visitor
155 */
156 public function accept(Visitor $visitor) {
157 foreach ($this->_collection as $element) {
158 $element->accept($visitor);
159 }
160 }
161 }
162
163
164
165 // client
166 $elementA = new ConcreteElementA("小花");
167 $elementB = new ConcreteElementB("云彩");
168
169 $visitor1 = new ConcreteVisitor1("路人甲");
170 $visitor2 = new ConcreteVisitor2("流氓乙");
171
172 $os = new ObjectStructure();
173 $os->attach($elementA);
174 $os->attach($elementB);
175
176 $os->accept($visitor1);
177 $os->accept($visitor2);
178
179
180
181 /*
182 哈哈, 小妞(小花), 给本大爷(路人甲)笑一个
183 哈哈, 小妞(云彩), 给本大爷(路人甲)笑一个
184 哈哈, 小妞(小花), 给本大爷(流氓乙)笑一个
185 哈哈, 小妞(云彩), 给本大爷(流氓乙)笑一个
186 */