定義:
訪問者模式(Visitor):表示一個作用于某物件結構中的各元素的操作,它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作,
結構:
- Visitor:抽象訪問者,為該物件結構中ConcreteElement的每一個類宣告一個Visit操作,
- ConcreteVisitor:具體訪問者,實作每個由Visitor宣告的操作,每個操作實作演算法的一部分,而該演算法片段乃是對應于結構中物件的類,
- Element:抽象類,定義一個Accept操作,它以一個訪問者為引數,
- ConcreteElement:具體元素,實作Accept操作,
- ObjectStructure:物件結構,能列舉它的元素,可以提供一個高層的介面以允許訪問者訪問它的元素,
- Client:客戶端代碼,
代碼實體:
/** * 抽象訪問者 * 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); // 結果 男人:成功時,背后多半有一個偉大的女人, 女人:成功時,背后大多有一個不成功的男人, 男人:失敗時,悶頭喝酒,誰也不用勸, 女人:失敗時,眼淚汪汪,誰也勸不了,
總結:
- 訪問者模式適用于資料結構相對穩定的系統,它把資料結構和作用于結構上的操作之間的耦合解脫開,使得操作集合可以相對自由地演化,
- 訪問者模式的目的是要把處理從資料結構分離出來,
- 訪問者模式的優點就是增加新的操作很容易,因為增加新的操作就意味著增加一個新的訪問者,訪問者模式將有關的行為集中到一個訪問者物件中,缺點其實也就是使增加新的資料結構變得困難了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/230561.html
標籤:其他
上一篇:PHP設計模式—訪問者模式
