訪問者模式(Visitor):表示一個做用於某對象結構中的各元素的操做。它使你能夠在不改變各元素的類的前提下定義做用於這些元素的新操做。算法
/** * 抽象訪問者 * Class VisitorState */ abstract class VisitorState { public $state_name; /** * 獲得男人的結論或反應 * @param ConcreteElementMan $concreteElementMan * @return mixed */ abstract public function getManConclusion(ConcreteElementMan $concreteElementMan); /** * 獲得女人的結論或反應 * @param ConcreteElementWoman $concreteElementWoman * @return mixed */ abstract public function getWomanConclusion(ConcreteElementWoman $concreteElementWoman); } /** * 抽象類,定義一個Accept操做 * Class ElementPerson */ abstract class ElementPerson { public $type_name; /** * 接受 * @param VisitorState $visitorState * @return mixed */ abstract public function accept(VisitorState $visitorState); } /** * 具體訪問者,成功狀態 * Class ConcreteVisitorSuccess */ class ConcreteVisitorSuccess extends VisitorState { public function __construct() { $this->state_name = '成功'; } public function getManConclusion(ConcreteElementMan $concreteElementMan) { // TODO: Implement getManConclusion() method. echo "{$concreteElementMan->type_name}:{$this->state_name}時,背後多半有一個偉大的女人。<br/>"; } public function getWomanConclusion(ConcreteElementWoman $concreteElementWoman) { // TODO: Implement getWomanConclusion() method. echo "{$concreteElementWoman->type_name}:{$this->state_name}時,背後大多有一個不成功的男人。<br/>"; } } /** * 具體訪問者,失敗狀態 * Class ConcreteVisitorFailing */ class ConcreteVisitorFailing extends VisitorState { public function __construct() { $this->state_name = '失敗'; } public function getManConclusion(ConcreteElementMan $concreteElementMan) { // TODO: Implement getManConclusion() method. echo "{$concreteElementMan->type_name}:{$this->state_name}時,悶頭喝酒,誰也不用勸。<br/>"; } public function getWomanConclusion(ConcreteElementWoman $concreteElementWoman) { // TODO: Implement getWomanConclusion() method. echo "{$concreteElementWoman->type_name}:{$this->state_name}時,眼淚汪汪,誰也勸不了。<br/>"; } } /** * 具體元素,男人 * Class ConcreteElementMan */ class ConcreteElementMan extends ElementPerson { public function __construct() { $this->type_name = '男人'; } public function accept(VisitorState $visitorState) { // TODO: Implement accept() method. $visitorState->getManConclusion($this); } } /** * 具體元素,女人 * Class ConcreteElementWoman */ class ConcreteElementWoman extends ElementPerson { public function __construct() { $this->type_name = '女人'; } public function accept(VisitorState $visitorState) { // TODO: Implement accept() method. $visitorState->getWomanConclusion($this); } } /** * 對象結構 * Class ObjectStructure */ class ObjectStructure { public $elements = []; /** * 添加 * @param ElementPerson $elementPerson */ public function add(ElementPerson $elementPerson) { $this->elements[] = $elementPerson; } /** * 移除 * @param ElementPerson $elementPerson */ public function remove(ElementPerson $elementPerson) { foreach ($this->elements as $key => $value) { if ($value == $elementPerson) { unset($this->elements[$key]); } } } /** * 查看顯示 * @param VisitorState $visitorState */ public function display(VisitorState $visitorState) { foreach ($this->elements as $element) { $element->accept($visitorState); } } } // 客戶端調用 $objectStructure = new ObjectStructure(); // 添加男人、女人 $objectStructure->add(new ConcreteElementMan()); $objectStructure->add(new ConcreteElementWoman()); // 成功時反應 $success = new ConcreteVisitorSuccess(); $objectStructure->display($success); // 失敗時反應 $failing = new ConcreteVisitorFailing(); $objectStructure->display($failing); // 結果 男人:成功時,背後多半有一個偉大的女人。 女人:成功時,背後大多有一個不成功的男人。 男人:失敗時,悶頭喝酒,誰也不用勸。 女人:失敗時,眼淚汪汪,誰也勸不了。