欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

學(xué)習(xí)php設(shè)計(jì)模式 php實(shí)現(xiàn)訪問者模式(Visitor)

 更新時(shí)間:2015年12月07日 10:48:25   作者:胖胖  
這篇文章主要介紹了php設(shè)計(jì)模式中的訪問者模式,使用php實(shí)現(xiàn)訪問者模式,感興趣的小伙伴們可以參考一下

訪問者模式表示一個(gè)作用于某對象結(jié)構(gòu)中各元素的操作。它可以在不修改各元素類的前提下定義作用于這些元素的新操作,即動(dòng)態(tài)的增加具體訪問者角色。
訪問者模式利用了雙重分派。先將訪問者傳入元素對象的Accept方法中,然后元素對象再將自己傳入訪問者,之后訪問者執(zhí)行元素的相應(yīng)方法。
訪問者模式多用在聚集類型多樣的情況下。在普通的形式下必須判斷每個(gè)元素是屬于什么類型然后進(jìn)行相應(yīng)的操作,從而誕生出冗長的條件轉(zhuǎn)移語句。而訪問者模式則可以比較好的解決這個(gè)問題。對每個(gè)元素統(tǒng)一調(diào)用$element->accept($vistor)即可。
訪問者模式多用于被訪問的類結(jié)構(gòu)比較穩(wěn)定的情況下,即不會隨便添加子類。訪問者模式允許被訪問結(jié)構(gòu)添加新的方法。
Visitor模式實(shí)際上是分離了對象結(jié)構(gòu)中的元素和對這些元素進(jìn)行操作的行為,從而使我們在根據(jù)對象結(jié)構(gòu)中的元素進(jìn)行方法調(diào)用的時(shí)候,不需要使用IF語句判斷,也就是封裝了操作。
但是,如果增加新的元素節(jié)點(diǎn),則會導(dǎo)致包括訪問者接口及其子類的改變,這就會違反了面向?qū)ο笾械?strong>開閉原則。
當(dāng)這種情況出現(xiàn)時(shí),一般表示訪問者模式已經(jīng)可能不再適用了,或者說設(shè)計(jì)時(shí)就有問題了!
一、Visitor模式結(jié)構(gòu)圖

二、Visitor模式中主要角色

1)抽象訪問者角色(Visitor):為該對象結(jié)構(gòu)(ObjectStructure)中的每一個(gè)具體元素提供一個(gè)訪問操作接口。該操作接口的名字和參數(shù)標(biāo)識了 要訪問的具體元素角色。這樣訪問者就可以通過該元素角色的特定接口直接訪問它。
2)具體訪問者角色(ConcreteVisitor):實(shí)現(xiàn)抽象訪問者角色接口中針對各個(gè)具體元素角色聲明的操作。
3)抽象節(jié)點(diǎn)(Node)角色:該接口定義一個(gè)accept操作接受具體的訪問者。
4)具體節(jié)點(diǎn)(Node)角色:實(shí)現(xiàn)抽象節(jié)點(diǎn)角色中的accept操作。
5) 對象結(jié)構(gòu)角色(ObjectStructure):這是使用訪問者模式必備的角色。它要具備以下特征:能枚舉它的元素;可以提供一個(gè)高層的接口以允許該訪問者訪問它的元素;可以是一個(gè)復(fù)合(組合模式)或是一個(gè)集合,如一個(gè)列表或一個(gè)無序集合(在PHP中我們使用數(shù)組代替,因?yàn)镻HP中的數(shù)組本來就是一個(gè)可以放置任何類型數(shù)據(jù)的集合)
三、Visitor模式的優(yōu)缺點(diǎn)
訪問者模式有如下的優(yōu)點(diǎn)
1)訪問者模式使得增加新的操作變得很容易。使用訪問者模式可以在不用修改具體元素類的情況下增加新的操作。它主要是通過元素類的accept方法來接受一個(gè)新的visitor對象來實(shí)現(xiàn)的。如果一些操作依賴于一個(gè)復(fù)雜的結(jié)構(gòu)對象的話,那么一般而言,增加新的操作會很復(fù)雜。而使用訪問者模式,增加新的操作就意味著增加一個(gè)新的訪問者類,因此,變得很容易。
2)訪問者模式將有關(guān)的行為集中到一個(gè)訪問者對象中,而不是分散到一個(gè)個(gè)的節(jié)點(diǎn)類中。
3)訪問者模式可以跨過幾個(gè)類的等級結(jié)構(gòu)訪問屬于不同的等級結(jié)構(gòu)的成員類。迭代子只能訪問屬于同一個(gè)類型等級結(jié)構(gòu)的成員對象,而不能訪問屬于不同等級結(jié)構(gòu)的對象。訪問者模式可以做到這一點(diǎn)。
4)積累狀態(tài)。每一個(gè)單獨(dú)的訪問者對象都集中了相關(guān)的行為,從而也就可以在訪問的過程中將執(zhí)行操作的狀態(tài)積累在自己內(nèi)部,而不是分散到很多的節(jié)點(diǎn)對象中。這是有益于系統(tǒng)維護(hù)的優(yōu)點(diǎn)。

訪問者模式有如下的缺點(diǎn)
1)增加新的節(jié)點(diǎn)類變得很困難。每增加一個(gè)新的節(jié)點(diǎn)都意味著要在抽象訪問者角色中增加一個(gè)新的抽象操作,并在每一個(gè)具體訪問者類中增加相應(yīng)的具體操作。
2)破壞封裝。訪問者模式要求訪問者對象訪問并調(diào)用每一個(gè)節(jié)點(diǎn)對象的操作,這隱含了一個(gè)對所有節(jié)點(diǎn)對象的要求:它們必須暴露一些自己的操作和內(nèi)部狀態(tài)。不然,訪問者的訪問就變得沒有意義。由于訪問者對象自己會積累訪問操作所需的狀態(tài),從而使這些狀態(tài)不再存儲在節(jié)點(diǎn)對象中,這也是破壞封裝的。

使用Visitor模式的前提: 對象群結(jié)構(gòu)中(Collection) 中的對象類型很少改變。
在接口Visitor和Element中,確保Element很少變化,也就是說,確保不能頻繁的添加新的Element元素類型加進(jìn)來,可以變化的是訪問者行為或操作,也就是Visitor的不同子類可以有多種,這樣使用訪問者模式最方便.
如果對象集合中的對象集合經(jīng)常有變化, 那么不但Visitor實(shí)現(xiàn)要變化,ConcreteVisitor也要增加相應(yīng)行為,GOF建議是,不如在這些對象類中直接逐個(gè)定義操作,無需使用訪問者設(shè)計(jì)模式。

四、Visitor模式與其它模式

1、如果所瀏覽的結(jié)構(gòu)對象是線性的,使用迭代模式而不是訪問者模式也是可以的
2、訪問者模式瀏覽合成模式的一些結(jié)構(gòu)對象
以上兩點(diǎn)來自《Java與模式》一書

五、Visitor模式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;
 }
 
 /**
 * 接受訪問者調(diào)用它針對該元素的新方法
 * @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;
 }
 
 /**
 * 接受訪問者調(diào)用它針對該元素的新方法
 * @param Visitor $visitor
 */
 public function accept(Visitor $visitor) {
 $visitor->visitConcreteElementB($this);
 }
 
}
 
/**
 * 對象結(jié)構(gòu) 即元素的集合
 */
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實(shí)現(xiàn)訪問者模式的代碼,還有一些關(guān)于訪問者模式的概念區(qū)分,希望對大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • php計(jì)算指定目錄下文件占用空間的方法

    php計(jì)算指定目錄下文件占用空間的方法

    這篇文章主要介紹了php計(jì)算指定目錄下文件占用空間的方法,實(shí)例分析了php操作目錄及文件的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • PHP 請求上下文相關(guān)總結(jié)

    PHP 請求上下文相關(guān)總結(jié)

    這篇文章主要介紹了PHP 請求上下文的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用PHP,感興趣的朋友可以了解下
    2021-04-04
  • php二維數(shù)組合并及去重復(fù)的方法

    php二維數(shù)組合并及去重復(fù)的方法

    這篇文章主要介紹了php二維數(shù)組合并及去重復(fù)的方法,實(shí)例分析了php合并數(shù)組與刪除重復(fù)項(xiàng)的技巧,需要的朋友可以參考下
    2015-03-03
  • php實(shí)現(xiàn)上傳圖片文件代碼

    php實(shí)現(xiàn)上傳圖片文件代碼

    在PHP程序開發(fā)中,文件上傳是一個(gè)使用非常普遍的功能,也是PHP程序員的必備技能之一。值得高興的是,在PHP中實(shí)現(xiàn)文件上傳功能要比在Java、C#等語言中簡單得多。下面我們結(jié)合具體的代碼實(shí)例來詳細(xì)介紹如何通過PHP實(shí)現(xiàn)文件上傳和多文件上傳功能。
    2015-07-07
  • PHP實(shí)現(xiàn)二維數(shù)組根據(jù)key進(jìn)行排序

    PHP實(shí)現(xiàn)二維數(shù)組根據(jù)key進(jìn)行排序

    這篇文章主要介紹了PHP實(shí)現(xiàn)二維數(shù)組根據(jù)key進(jìn)行排序,在PHP中內(nèi)置了很多對數(shù)組進(jìn)行處理的函數(shù),有很多時(shí)候我們直接使用其內(nèi)置函數(shù)就能達(dá)到我們的需求,得到我們所想要的結(jié)果,需要的朋友可以參考下
    2023-10-10
  • PHP 7.1中利用OpenSSL代替Mcrypt加解密的方法詳解

    PHP 7.1中利用OpenSSL代替Mcrypt加解密的方法詳解

    最近在開發(fā)微信公眾號功能的時(shí)候發(fā)現(xiàn)在PHP 7.1中Mcrypt已經(jīng)被棄用了,無奈只能找對應(yīng)的解決方法來替代,所以這篇文章主要給大家介紹了關(guān)于在PHP 7.1中利用OpenSSL代替Mcrypt加解密的相關(guān)資料,需要的朋友可以參考下。
    2017-11-11
  • php基于DOMDocument操作頁面元素實(shí)例

    php基于DOMDocument操作頁面元素實(shí)例

    這篇文章主要介紹了php基于DOMDocument操作頁面元素,結(jié)合實(shí)例形式分析了php使用DOMDocument進(jìn)行頁面元素獲取與屬性修改的相關(guān)操作技巧,需要的朋友可以參考下
    2023-06-06
  • php selectradio和checkbox默認(rèn)選擇的實(shí)現(xiàn)方法詳解

    php selectradio和checkbox默認(rèn)選擇的實(shí)現(xiàn)方法詳解

    本篇文章是對php selectradio和checkbox默認(rèn)選擇的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • php 文本文件的讀取效率

    php 文本文件的讀取效率

    一直鼓搗著想把博客的首頁存在文件里,結(jié)果存在文件里,博客更新時(shí)再重新將內(nèi)容再次寫入到這個(gè)文件。所以剛才測試了三種讀取文本的常規(guī)方法
    2012-02-02
  • php日期操作技巧小結(jié)

    php日期操作技巧小結(jié)

    這篇文章主要介紹了php日期操作技巧,涉及php日期與時(shí)間的顯示格式轉(zhuǎn)換技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06

最新評論