• 访问者模式


      我们去银行柜台办业务,一般情况下会开几个个人业务柜台的,你去其中任何一个柜台办理都是可以的。
    我们的访问者模式可以很好付诸在这个场景中:对于银行柜台来说,他们是不用变化的,就是说今天和明天提供个人业务的柜台是不需要有变化的。
    而我们作为访问者,今天来银行可能是取消费流水,明天来银行可能是去办理手机银行业务,这些是我们访问者的操作,一直是在变化的。   访问者模式主要将数据结构与数据操作分离。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操,即动态的添加访问者角色。   访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。   访问者模式利用了双重分派。先将访问者传入元素对象的Accept方法中,然后元素对象再将自己传入访问者,之后访问者执行元素的相应方法。   访问者模式使得增加新的操作变得很容易。使用访问者模式可以在不用修改具体元素类的情况下增加新的操作。它主要是通过元素类的accept方法来接受一个新的visitor对象来实现的。
    如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的访问者类,因此,变得很容易。
      积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点

      1 <?php
      2 
      3 /**
      4  * 和观察者模式有一丝相似
      5  */
      6 
      7 /**
      8  * 抽象访问者角色, 要定义好针对所有元素的处理操作
      9  */
     10 interface Visitor {
     11     public function visitConcreteElementA(ConcreteElementA $elementA);
     12     public function visitConcreteElementB(concreteElementB $elementB);
     13 }
     14 
     15 /**
     16  * 抽象元素角色
     17  */
     18 interface Element {
     19     public function accept(Visitor $visitor);
     20 }
     21 
     22 
     23 
     24 
     25 
     26 /**
     27  * 具体的访问者1
     28  */
     29 class ConcreteVisitor1 implements Visitor {
     30     private $_name;
     31 
     32     public function __construct($name)
     33     {
     34         $this->_name = $name;
     35     }
     36 
     37     public function visitConcreteElementA(ConcreteElementA $elementA)
     38     {
     39         echo "<br/>", "哈哈, 小妞({$elementA->getName()}), 给本大爷({$this->_name})笑一个";
     40     }
     41 
     42     public function visitConcreteElementB(ConcreteElementB $elementB)
     43     {
     44         echo "<br/>", "哈哈, 小妞({$elementB->getName()}), 给本大爷({$this->_name})笑一个";
     45     }
     46 }
     47 
     48 /**
     49  * 具体的访问者2
     50  */
     51 class ConcreteVisitor2 implements Visitor {
     52     private $_name;
     53 
     54     public function __construct($name)
     55     {
     56         $this->_name = $name;
     57     }
     58 
     59     public function visitConcreteElementA(ConcreteElementA $elementA)
     60     {
     61         echo "<br/>", "哈哈, 小妞({$elementA->getName()}), 给本大爷({$this->_name})笑一个";
     62     }
     63 
     64     public function visitConcreteElementB(ConcreteElementB $elementB)
     65     {
     66         echo "<br/>", "哈哈, 小妞({$elementB->getName()}), 给本大爷({$this->_name})笑一个";
     67     }
     68 }
     69 
     70 
     71 
     72 
     73 
     74 /**
     75  * 具体元素A
     76  */
     77 class ConcreteElementA implements Element {
     78     private $_name;
     79 
     80     public function __construct($name)
     81     {
     82         $this->_name = $name;
     83     }
     84 
     85     public function getName()
     86     {
     87         return $this->_name;
     88     }
     89 
     90     /**
     91      * @param Visitor $visitor  接受访问者调用它针对该元素的新方法
     92      */
     93     public function accept(Visitor $visitor)
     94     {
     95         $visitor->visitConcreteElementA($this);
     96     }
     97 }
     98 
     99 /**
    100  * 具体元素B
    101  */
    102 class ConcreteElementB implements Element {
    103     private $_name;
    104 
    105     public function __construct($name)
    106     {
    107         $this->_name = $name;
    108     }
    109 
    110     public function getName()
    111     {
    112         return $this->_name;
    113     }
    114 
    115     /**
    116      * @param Visitor $visitor  接受访问者调用它针对该元素的新方法
    117      */
    118     public function accept(Visitor $visitor)
    119     {
    120         $visitor->visitConcreteElementB($this);
    121     }
    122 }
    123 
    124 
    125 
    126 
    127 /**
    128  * 对象结构 即元素的集合
    129  */
    130 class ObjectStructure {
    131     private $_collection;           //具体的元素的集合
    132 
    133     public function __construct()
    134     {
    135         $this->_collection = [];
    136     }
    137 
    138     public function attach(Element $element) {
    139         return array_push($this->_collection, $element);
    140     }
    141 
    142     public function detach(Element $element) {
    143         $index = array_search($element, $this->_collection);
    144 
    145         if ($index !== FALSE) {
    146             unset($this->_collection[$index]);
    147         }
    148         return $index;
    149     }
    150 
    151     /**
    152      * 访问者可以访问这些元素集合
    153      *
    154      * @param Visitor $visitor
    155      */
    156     public function accept(Visitor $visitor) {
    157         foreach ($this->_collection as $element) {
    158             $element->accept($visitor);
    159         }
    160     }
    161 }
    162 
    163 
    164 
    165 // client
    166 $elementA = new ConcreteElementA("小花");
    167 $elementB = new ConcreteElementB("云彩");
    168 
    169 $visitor1 = new ConcreteVisitor1("路人甲");
    170 $visitor2 = new ConcreteVisitor2("流氓乙");
    171 
    172 $os = new ObjectStructure();
    173 $os->attach($elementA);
    174 $os->attach($elementB);
    175 
    176 $os->accept($visitor1);
    177 $os->accept($visitor2);
    178 
    179 
    180 
    181 /*
    182     哈哈, 小妞(小花), 给本大爷(路人甲)笑一个
    183     哈哈, 小妞(云彩), 给本大爷(路人甲)笑一个
    184     哈哈, 小妞(小花), 给本大爷(流氓乙)笑一个
    185     哈哈, 小妞(云彩), 给本大爷(流氓乙)笑一个
    186  */
    View Code
  • 相关阅读:
    LumaQQ.NET协议过期及解决办法
    帮助中国移动设计10086的排队小模块 Virus
    《宫锁心玉》观后感 Virus
    WCF扩展:行为扩展Behavior Extension<一> Virus
    谈谈我对实体的认识:DTO,DMO,DPO Virus
    自定义ORM系列(三)工具雏形及基本用法 Virus
    随笔写下的开发流程 Virus
    自定义ORM系列(二)发现属性是否修改,有选择的持久化 Virus
    我对DDD的认知(一) Virus
    胡乱说一下我对于 BO VO PO DTO 的理解 Virus
  • 原文地址:https://www.cnblogs.com/hangtt/p/6265491.html
Copyright © 2020-2023  润新知