聲明:本系列博客參考資料《大話設計模式》,作者程傑。
訪問者模式表示一個作用於某對象結構中的各元素的操作。
它使你能夠在不改變各元素類的前提下定義作用於這些元素的新操作。
UML類圖:
角色:
1.抽象訪問者(State):為該對象結構中詳細元素角色聲明一個訪問操作接口。
該操作接口的名字和參數標識了發送訪問請求給詳細訪問者的詳細元素角色,這樣訪問者就能夠通過該元素角色的特定接口直接訪問它。
2.詳細訪問者(Success):實現訪問者聲明的接口。
3.抽象元素(Person):定義一個接受訪問操作accept(),它以一個訪問者作為參數。
4. 詳細元素(Man):實現了抽象元素所定義的接受操作接口。
5.結構對象(ObjectStruct):這是使用訪問者模式必備的角色。
它具備下面特性:能枚舉它的元素。能夠提供一個高層接口以同意訪問者訪問它的元素;如有須要,能夠設計成一個復合對象或者一個聚集(如一個列表或無序集合)。
核心代碼:
<span style="color:#000000;"><?php /** * Created by PhpStorm. * User:Jang * Date:2015/6/11 * Tim: 9 :40 */ /*男人這本書的內容要比封面吸引人;女人這本書的封面通常比內容更吸引人 男人成功時。背後多半有一個偉大的女人;女人成功時,背後多半有一個失敗的男人 男人失敗時,悶頭喝酒,誰也不用勸。女人失敗時,眼淚汪汪,誰也勸不了 男人戀愛時,凡事不懂也要裝懂。女人戀愛時。遇事懂也要裝作不懂*/ //抽象狀態 abstract class State { protected $state_name; //得到男人反應 public abstract function GetManAction(VMan $elementM); //得到女人反應 public abstract function GetWomanAction(VWoman $elementW); } //抽象人 abstract class Person { public $type_name; public abstract function Accept(State $visitor); } //成功狀態 class Success extends State { public function __construct() { $this->state_name="成功"; } public function GetManAction(VMan $elementM) { echo "{$elementM->type_name}:{$this->state_name}時,背後多半有一個偉大的女人。<br/>"; } public function GetWomanAction(VWoman $elementW) { echo "{$elementW->type_name} :{$this->state_name}時。背後大多有一個不成功的男人。<br/>"; } } //失敗狀態 class Failure extends State { public function __construct() { $this->state_name="失敗"; } public function GetManAction(VMan $elementM) { echo "{$elementM->type_name}:{$this->state_name}時,悶頭喝酒,誰也不用勸。<br/>"; } public function GetWomanAction(VWoman $elementW) { echo "{$elementW->type_name} :{$this->state_name}時。眼淚汪汪,誰也勸不了。<br/>"; } } //戀愛狀態 class Amativeness extends State { public function __construct() { $this->state_name="戀愛"; } public function GetManAction(VMan $elementM) { echo "{$elementM->type_name}:{$this->state_name}時,凡事不懂也要裝懂。<br/>"; } public function GetWomanAction(VWoman $elementW) { echo "{$elementW->type_name} :{$this->state_name}時,遇事懂也要裝作不懂。<br/>"; } } //男人 class VMan extends Person { function __construct() { $this->type_name="男人"; } public function Accept(State $visitor) { $visitor->GetManAction($this); } } //女人 class VWoman extends Person { public function __construct() { $this->type_name="女人"; } public function Accept(State $visitor) { $visitor->GetWomanAction($this); } } //對象結構 class ObjectStruct { private $elements=array(); //添加 public function Add(Person $element) { array_push($this->elements,$element); } //移除 public function Remove(Person $element) { foreach($this->elements as $k=>$v) { if($v==$element) { unset($this->elements[$k]); } } } //查看顯示 public function Display(State $visitor) { foreach ($this->elements as $v) { $v->Accept($visitor); } } }</span>
header("Content-Type:text/html;charset=utf-8"); //------------------------訪問者模式-------------------- require_once "./Visitor/Visitor.php"; $os = new ObjectStruct(); $os->Add(new VMan()); $os->Add(new VWoman()); //成功時反應 $ss = new Success(); $os->Display($ss); //失敗時反應 $fs = new Failure(); $os->Display($fs); //戀愛時反應 $ats=new Amativeness(); $os->Display($ats);
1) 一個對象結構包括非常多類對象。它們有不同的接口,而你想對這些對象實施一些依賴於其詳細類的操作。
2) 須要對一個對象結構中的對象進行非常多不同的而且不相關的操作。而你想避免讓這些操作“污染”這些對象的類。
Visitor模式使得你能夠將相關的操作集中起來定義在一個類中。
3) 當該對象結構被非常多應用共享時,用Visitor模式讓每一個應用僅包括須要用到的操作。
4) 定義對象結構的類非常少改變。但常常須要在此結構上定義新的操作。
改變對象結構類須要重定義對全部訪問者的接口,這可能須要非常大的代價。
假設對象結構類常常改變。那麼可能還是在這些類中定義這些操作較好。
歡迎關注我的視頻課程。地址例如以下,謝謝。