宝哥软件园

学习php设计模式php实现访问者模式

编辑:宝哥软件园 来源:互联网 时间:2021-09-21

访问者模式表示作用于对象结构中每个元素的操作。它可以在不修改每个元素类的情况下定义作用于这些元素的新操作,即动态添加特定的访问者角色。访问者模式使用双重分配。将访问者传递到元素对象的Accept方法中,然后元素对象将自身传递给访问者,然后访问者执行元素的相应方法。当有各种聚合类型时,经常使用访问者模式。在普通形式中,需要判断每个元素属于什么类型,然后进行相应的操作,从而产生冗长的条件转移语句。访客模式可以更好地解决这个问题。只需为每个元素统一调用$element-accept($vistor)。访问者模式多在被访问的类结构相对稳定时使用,即不会随便添加子类。访问者模式允许被访问的结构添加新的方法。事实上,Visitor模式将对象结构中的元素与操作这些元素的行为分开,这样我们在根据对象结构中的元素调用方法时就不需要用IF语句来判断,也就是封装操作。但是,如果添加了一个新的元素节点,就会导致包括访问者接口及其子类在内的变化,这将违反面向对象中的开放封闭原则。当这种情况发生时,通常意味着访问者模式可能不再适用,或者设计有问题!一、访客模式结构图。

第二,访问者模型中的主要角色。

1)抽象访问者角色:为ObjectStructure中的每个具体元素提供访问操作接口。操作接口的名称和参数标识了要访问的特定元素角色。以便访问者可以通过元素角色的特定界面直接访问它。2) ConcreteVisitor):实现抽象访问者角色接口中为每个具体元素角色声明的操作。3)抽象节点角色:这个接口定义了一个接受操作来接受特定的访问者。4)具体节点角色:在抽象节点角色中实现接受操作。5) ObjectStructure角色:这是使用访问者模式的必要角色。它应该具有以下特点:能够列举其要素;可以提供高级接口来允许访问者访问它的元素;它可以是复合(组合模式)或集合,如列表或无序集合(在PHP中,我们使用数组代替,因为PHP中的数组最初是一个可以放置任何类型数据的集合)。3.Visitor模式的优缺点Visitor模式有以下优点:1) Visitor模式使添加新操作变得容易。使用访问者模式,您可以在不修改特定元素类的情况下添加新操作。它主要是通过元素类的accept方法接受一个新的访问者对象来实现的。如果某些操作依赖于复杂的结构对象,则添加新操作通常会很复杂。使用访问者模式,添加一个新的操作意味着添加一个新的访问者类,所以变得很容易。2)访问者模式将相关行为集中在一个访问者对象中,而不是将它们分散到节点类中。3)访问者模式可以跨几个类的层次结构访问属于不同层次结构的成员类。迭代只能访问属于同一类型层次结构的成员对象,但不能访问属于不同层次结构的对象。访问者模式可以做到这一点。4)积累状态。每个单独的访问者对象都集中在相关的行为上,这样执行操作的状态就可以在访问的过程中积累在自身,而不是分散到很多节点对象上。这有利于系统维护。

访问者模式有以下缺点:1)很难添加新的节点类。添加新节点意味着在抽象访问者角色中添加新的抽象操作,并在每个具体的访问者类中添加相应的具体操作。2)销毁包装。访问者模式要求访问者对象访问和调用每个节点对象的操作,这意味着对所有节点对象的要求:它们必须公开自己的一些操作和内部状态。否则,访问者的访问将变得毫无意义。因为访问者对象本身积累了访问操作所需的状态,所以这些状态不再存储在节点对象中,这也破坏了封装。

使用Visitor模式的前提是对象组结构中的对象类型很少改变。在visitor和Element接口中,保证Element很少变化,也就是保证新元素类型不能频繁添加,但是能变化的是Visitor的行为或者操作,也就是Visitor有很多不同的子类,所以使用Visitor模式最方便。如果对象集中的对象集经常改变,不仅访问者实现会改变,混凝土访问者也应该添加相应的行为。GOF建议,最好不使用访问者设计模式,直接在这些对象类中逐个定义操作。

四.访客模式和其他模式。

1.如果浏览的结构对象是线性的,可以使用迭代模式而不是访问者模式。2.访问者模式以复合模式浏览一些结构对象。以上两点来源于《Java与模式》这本书。

动词(verb的缩写)访问者模式的PHP示例。

?服务器端编程语言(Professional Hypertext Preprocessor的缩写)接口访问者{公共函数visitConcreteElementA(混凝土元素a $ ElEMENTa);公共函数visitConcreteElementB(混凝土元素b $要素b);}接口元素{公共函数接受(访问者$ Visitor);} /** * 具体的访问者1 */class concreditvisitor 1实现visitor { public function visitConcreteElementA(混凝土元素a $ elementA){ echo $ elementA-getName().由' ConcerteVisitor1 br /'访问;}公共函数visitConcreteElementB(混凝土元素b $ ElEMENTb){ echo $ ElEMENTb-GetName().' ConcerteVisitor1 br /'访问过;} } /** * 具体的访问者2 */class concreditvisitor 2实现visitor { public function visitConcreteElementA(混凝土元素a $ elementA){ echo $ elementA-getName().由' ConcerteVisitor2 br /'访问;}公共函数visitConcreteElementB(混凝土元素b $ ElEMENTb){ echo $ ElEMENTb-GetName().' ConcerteVisitor2 br /'访问过;} } /** * 具体元素一个*/class混凝土元素a实现了元素{ 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 */混凝土元素b类实现元素{ 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对象结构{ private $ _ collectionpublic function _ _ construct(){ $ this-_ collection=array();}公共函数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]);}返回$ index}公共函数accept(Visitor $ Visitor){ foreach($ this-_ collection as $ element){ $ element-accept($ Visitor);} }}类客户端{ /** *主程序*/public static function main(){ $ ElEMENTa=new concrete ElEMENTa(' ElEMENTa ');$elementB=新的混凝土元素b('元素b ');$elementA2=新的混凝土元素b(‘元素a2’);$ visitor 1=新混凝土访客1();$ visitor 2=新混凝土访客2();$ OS=新对象结构();$ OS-attach($ ElEMENTa);$ OS-attach($ element b);$ OS-attach($元素a2);$ OS-detach($ ElEMENTa);$ OS-接受($访客1);$ OS-接受($访客2);} }客户端:3360 main();以上就是使用服务器端编程语言(专业超文本预处理器的缩写)实现访问者模式的代码,还有一些关于访问者模式的概念区分,希望对大家的学习有所帮助。

更多资讯
游戏推荐
更多+