zoukankan      html  css  js  c++  java
  • PHP草根论之设计模式-訪问者模式

    关于模式本身的概念,请參考网上其他文章

    此处仅仅讨论在PHP实际开发过程中的应用


    此模式适用范围极为受限,适用情景:

    1.适用于项目维护过程,不适用于项目开发过程

    2.新增需求,要求为一个/多个类添加一个/多个,同样/相似的方法

    3.原有代码不能改动或扩展

    4.原有类已经预留了一个为本模式准备的接口.

    以上,3,4非常难同一时候在产品维护过程中同一时候出现.

     

    需求:

    1.一组对象,同属一个父类或分属不同父类,使用某一数据结构组成一个数据集,此处的数据结构能够是概念意义上的队列,,集合,,图或实际意义上的一维或多维数组,仅仅要能够遍历就可以

    2.项目须要对以上对象添加一个操作,以便在遍历整组对象时,同名调用.

     

    实现过程:

    1.原有代码中,以上对象所属的类,事先预留了一个扩展接口,能够叫做accept(奇怪的名字)

    Class ElementA{

    public function accept(VisitorBase $v){

    $v->visitA($this);

    }

    }

    class ElementB{

    public function accept(VisitorBase $v){

    $v->visitB($this);

    }

     

    }

    依据以上,我们当然要事先定义一个VisitorBase的抽象接口

    interface VisitorBase {

    function visitA(ElementA $eleA);

    function visitB(ElementB $eleB);

    }

    2.新的代码中,我们为新增的操作创建一个类,叫做VisitorX(訪问者,又是一个奇怪的名称),假设有还有一个操作,能够定义为VisitorY,均实现了VisitorBase接口

    class VisitorX implements VisitorBase{

    public function visitA(ElementA $eleA){

    //此处能够訪问元素A的方法以处理详细事务

    $eleA->someFunc();

    }

    public function visitB(ElementB $eleB){

    ……

    }

    }

    3.新的代码中,我们能够遍历,以数组为例(这个最经常使用了)

        $x=new VisitorX;

        foreach($elementArray as $element){

            $element->accept($x);

        }

        以上将遍历全部元素(不管是否同一父类),对每个元素运行VisitorX类中的对应操作.


    草根观点:

        1.凭什么原有代码不让改动?仅仅是加个方法而已.

        2.我不改原有代码,还不让我继承一下,扩展一个方法?

        3.原有代码定义扩展接口了么?

    曾经的程序猿有这么前瞻?

        4.仅仅要有其他方式实现同等功能,尽量不要使用此设计模式, 这将导致对同一对象的操作代码分散在程序的不同位置,不利于进一步的维护与改动.

        5.可考虑的替代实现方法:

           A.改动原有类,添加一个同名方法

           B.扩展(继承)原有类,添加一个同名方法

           C.假设一定要将不同类的同一操作的代码集中在一起,那么考虑Trait吧



  • 相关阅读:
    AC自动机【萌新文章】
    ubuntu安装pandas
    pandas.Series函数用法
    关于scikit-learn
    关于scikit-learn
    Ubuntu安装openmpi
    Ubuntu分区小知识与分区方案
    Ubuntu16.04安装x11VNC远程桌面
    Ubuntu用户权限管理(chown, chmod)
    Ubuntu新建用户组
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5063177.html
Copyright © 2011-2022 走看看