《PHP學習:學習php設計模式 php實現訪問者模式(Visitor)》要點:
本文介紹了PHP學習:學習php設計模式 php實現訪問者模式(Visitor),希望對您有用。如果有疑問,可以聯系我們。
拜訪者模式表示一個作用于某對象結構中各元素的操作.它可以在不修改各元素類的前提下定義作用于這些元素的新操作,即動態的增加具體拜訪者角色.
拜訪者模式利用了雙重分派.先將拜訪者傳入元素對象的Accept方法中,然后元素對象再將自己傳入拜訪者,之后拜訪者執行元素的相應方法.
拜訪者模式多用在聚集類型多樣的情況下.在普通的形式下必須判斷每個元素是屬于什么類型然后進行相應的操作,從而誕生出冗長的條件轉移語句.而拜訪者模式則可以比較好的解決這個問題.對每個元素統一調用$element->accept($vistor)即可.
拜訪者模式多用于被拜訪的類結構比較穩定的情況下,即不會隨便添加子類.拜訪者模式允許被拜訪結構添加新的方法.
Visitor模式實際上是分離了對象結構中的元素和對這些元素進行操作的行為,從而使我們在根據對象結構中的元素進行方法調用的時候,不需要使用IF語句判斷,也就是封裝了操作.
但是,如果增加新的元素節點,則會導致包括拜訪者接口及其子類的改變,這就會違反了面向對象中的開閉原則.
當這種情況出現時,一般表示拜訪者模式已經可能不再適用了,或者說設計時就有問題了!
一、Visitor模式結構圖
PHP教程
PHP教程
二、Visitor模式中主要角色PHP教程
1)抽象拜訪者角色(Visitor):為該對象結構(ObjectStructure)中的每一個具體元素提供一個拜訪操作接口.該操作接口的名字和參數標識了 要拜訪的具體元素角色.這樣拜訪者就可以通過該元素角色的特定接口直接拜訪它.
2)具體拜訪者角色(ConcreteVisitor):實現抽象拜訪者角色接口中針對各個具體元素角色聲明的操作.
3)抽象節點(Node)角色:該接口定義一個accept操作接受具體的拜訪者.
4)具體節點(Node)角色:實現抽象節點角色中的accept操作.
5) 對象結構角色(ObjectStructure):這是使用拜訪者模式必備的角色.它要具備以下特征:能枚舉它的元素;可以提供一個高層的接口以允許該拜訪者拜訪它的元素;可以是一個復合(組合模式)或是一個集合,如一個列表或一個無序集合(在PHP中我們使用數組代替,因為PHP中的數組本來就是一個可以放置任何類型數據的集合)
三、Visitor模式的優缺點
拜訪者模式有如下的優點:
1)拜訪者模式使得增加新的操作變得很容易.使用拜訪者模式可以在不用修改具體元素類的情況下增加新的操作.它主要是通過元素類的accept方法來接受一個新的visitor對象來實現的.如果一些操作依賴于一個復雜的結構對象的話,那么一般而言,增加新的操作會很復雜.而使用拜訪者模式,增加新的操作就意味著增加一個新的拜訪者類,因此,變得很容易.
2)拜訪者模式將有關的行為集中到一個拜訪者對象中,而不是分散到一個個的節點類中.
3)拜訪者模式可以跨過幾個類的等級結構拜訪屬于不同的等級結構的成員類.迭代子只能拜訪屬于同一個類型等級結構的成員對象,而不能拜訪屬于不同等級結構的對象.拜訪者模式可以做到這一點.
4)積累狀態.每一個單獨的拜訪者對象都集中了相關的行為,從而也就可以在拜訪的過程中將執行操作的狀態積累在自己內部,而不是分散到很多的節點對象中.這是有益于系統維護的優點.PHP教程
拜訪者模式有如下的缺點:
1)增加新的節點類變得很困難.每增加一個新的節點都意味著要在抽象拜訪者角色中增加一個新的抽象操作,并在每一個具體拜訪者類中增加相應的具體操作.
2)破壞封裝.拜訪者模式要求拜訪者對象拜訪并調用每一個節點對象的操作,這隱含了一個對所有節點對象的要求:它們必須暴露一些自己的操作和內部狀態.不然,拜訪者的拜訪就變得沒有意義.由于拜訪者對象自己會積累拜訪操作所需的狀態,從而使這些狀態不再存儲在節點對象中,這也是破壞封裝的.PHP教程
使用Visitor模式的前提: 對象群結構中(Collection) 中的對象類型很少改變.
在接口Visitor和Element中,確保Element很少變化,也就是說,確保不能頻繁的添加新的Element元素類型加進來,可以變化的是拜訪者行為或操作,也就是Visitor的不同子類可以有多種,這樣使用拜訪者模式最方便.
如果對象集合中的對象集合經常有變化, 那么不但Visitor實現要變化,ConcreteVisitor也要增加相應行為,GOF建議是,不如在這些對象類中直接逐個定義操作,無需使用拜訪者設計模式.PHP教程
四、Visitor模式與其它模式PHP教程
1、如果所瀏覽的結構對象是線性的,使用迭代模式而不是拜訪者模式也是可以的
2、拜訪者模式瀏覽合成模式的一些結構對象
以上兩點來自《Java與模式》一書PHP教程
五、Visitor模式PHP示例
PHP教程
<?php interface Visitor { public function visitConcreteElementA(ConcreteElementA $elementA); public function visitConcreteElementB(concreteElementB $elementB); } interface Element { public function accept(Visitor $visitor); } /** * 具體的拜訪者1 */ class ConcreteVisitor1 implements Visitor { public function visitConcreteElementA(ConcreteElementA $elementA) { echo $elementA->getName() . " visitd by ConcerteVisitor1 <br />"; } public function visitConcreteElementB(ConcreteElementB $elementB) { echo $elementB->getName() . " visited by ConcerteVisitor1 <br />"; } } /** * 具體的拜訪者2 */ class ConcreteVisitor2 implements Visitor { public function visitConcreteElementA(ConcreteElementA $elementA) { echo $elementA->getName() . " visitd by ConcerteVisitor2 <br />"; } public function visitConcreteElementB(ConcreteElementB $elementB) { echo $elementB->getName() . " visited by ConcerteVisitor2 <br />"; } } /** * 具體元素A */ class ConcreteElementA implements Element { private $_name; public function __construct($name) { $this->_name = $name; } public function getName() { return $this->_name; } /** * 接受拜訪者調用它針對該元素的新方法 * @param Visitor $visitor */ public function accept(Visitor $visitor) { $visitor->visitConcreteElementA($this); } } /** * 具體元素B */ class ConcreteElementB implements Element { private $_name; public function __construct($name) { $this->_name = $name; } public function getName() { return $this->_name; } /** * 接受拜訪者調用它針對該元素的新方法 * @param Visitor $visitor */ public function accept(Visitor $visitor) { $visitor->visitConcreteElementB($this); } } /** * 對象結構 即元素的集合 */ class ObjectStructure { private $_collection; public function __construct() { $this->_collection = array(); } public function attach(Element $element) { return array_push($this->_collection, $element); } public function detach(Element $element) { $index = array_search($element, $this->_collection); if ($index !== FALSE) { unset($this->_collection[$index]); } return $index; } public function accept(Visitor $visitor) { foreach ($this->_collection as $element) { $element->accept($visitor); } } } class Client { /** * Main program. */ public static function main() { $elementA = new ConcreteElementA("ElementA"); $elementB = new ConcreteElementB("ElementB"); $elementA2 = new ConcreteElementB("ElementA2"); $visitor1 = new ConcreteVisitor1(); $visitor2 = new ConcreteVisitor2(); $os = new ObjectStructure(); $os->attach($elementA); $os->attach($elementB); $os->attach($elementA2); $os->detach($elementA); $os->accept($visitor1); $os->accept($visitor2); } } Client::main(); ?>
以上就是使用php實現拜訪者模式的代碼,還有一些關于拜訪者模式的概念區分,希望對大家的學習有所幫助.PHP教程
歡迎參與《PHP學習:學習php設計模式 php實現訪問者模式(Visitor)》討論,分享您的想法,維易PHP學院為您提供專業教程。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/8310.html