PHP设计模式——訪问者模式

声明:本系列博客參考资料《大话设计模式》,作者程杰。


      訪问者模式表示一个作用于某对象结构中的各元素的操作。

它使你能够在不改变各元素类的前提下定义作用于这些元素的新操作。


      UML类图:  

      


         角色:        

        1.抽象訪问者(State):为该对象结构中详细元素角色声明一个訪问操作接口。

该操作接口的名字和參数标识了发送訪问请求给详细訪问者的详细元素角色,这样訪问者就能够通过该元素角色的特定接口直接訪问它。

        2.详细訪问者(Success):实现訪问者声明的接口。

        3.抽象元素(Person):定义一个接受訪问操作accept(),它以一个訪问者作为參数。


        4. 详细元素(Man):实现了抽象元素所定义的接受操作接口。

        5.结构对象(ObjectStruct):这是使用訪问者模式必备的角色。

它具备下面特性:能枚举它的元素。能够提供一个高层接口以同意訪问者訪问它的元素;如有须要,能够设计成一个复合对象或者一个聚集(如一个列表或无序集合)。


        核心代码:

       

<span style="color:#000000;"><?php
/**
 * Created by PhpStorm.
 * User:Jang
 * Date:2015/6/11
 * Tim: 9 :40
 */

/*男人这本书的内容要比封面吸引人;女人这本书的封面通常比内容更吸引人
男人成功时。背后多半有一个伟大的女人;女人成功时,背后多半有一个失败的男人
男人失败时,闷头喝酒,谁也不用劝。女人失败时,眼泪汪汪,谁也劝不了
男人恋爱时,凡事不懂也要装懂。女人恋爱时。遇事懂也要装作不懂*/
//抽象状态
abstract class State
{
    protected $state_name;

    //得到男人反应
    public abstract function GetManAction(VMan $elementM);
    //得到女人反应
    public abstract function GetWomanAction(VWoman $elementW);
}

//抽象人
abstract class Person
{
    public $type_name;

    public abstract function Accept(State $visitor);
}

//成功状态
class Success extends State
{
    public function __construct()
    {
        $this->state_name="成功";
    }

    public  function GetManAction(VMan $elementM)
    {
        echo "{$elementM->type_name}:{$this->state_name}时,背后多半有一个伟大的女人。<br/>";
    }

    public  function GetWomanAction(VWoman $elementW)
    {
        echo "{$elementW->type_name} :{$this->state_name}时。背后大多有一个不成功的男人。<br/>";
    }
}

//失败状态
class Failure extends State
{
    public function __construct()
    {
        $this->state_name="失败";
    }

    public  function GetManAction(VMan $elementM)
    {
        echo "{$elementM->type_name}:{$this->state_name}时,闷头喝酒,谁也不用劝。<br/>";
    }

    public  function GetWomanAction(VWoman $elementW)
    {
        echo "{$elementW->type_name} :{$this->state_name}时。眼泪汪汪,谁也劝不了。<br/>";
    }
}

//恋爱状态
class Amativeness  extends State
{
    public function __construct()
    {
        $this->state_name="恋爱";
    }

    public  function GetManAction(VMan $elementM)
    {
        echo "{$elementM->type_name}:{$this->state_name}时,凡事不懂也要装懂。<br/>";
    }

    public  function GetWomanAction(VWoman $elementW)
    {
        echo "{$elementW->type_name} :{$this->state_name}时,遇事懂也要装作不懂。<br/>";
    }
}

//男人
class VMan extends Person
{
    function __construct()
    {
        $this->type_name="男人";
    }

    public  function Accept(State $visitor)
    {
        $visitor->GetManAction($this);
    }
}

//女人
class VWoman extends Person
{
    public function __construct()
    {
        $this->type_name="女人";
    }

    public  function Accept(State $visitor)
    {
        $visitor->GetWomanAction($this);
    }
}

//对象结构
class ObjectStruct
{
    private $elements=array();
    //添加
    public function Add(Person $element)
    {
        array_push($this->elements,$element);
    }
    //移除
    public function Remove(Person $element)
    {
        foreach($this->elements as $k=>$v)
        {
            if($v==$element)
            {
                unset($this->elements[$k]);
            }
        }
    }

    //查看显示
    public function Display(State $visitor)
    {
        foreach ($this->elements as $v)
        {
            $v->Accept($visitor);
        }
    }
}</span>

        測试client代码:

       

header("Content-Type:text/html;charset=utf-8");
//------------------------訪问者模式--------------------
require_once "./Visitor/Visitor.php";
$os = new ObjectStruct();
$os->Add(new VMan());
$os->Add(new VWoman());

//成功时反应
$ss = new Success();
$os->Display($ss);

//失败时反应
$fs = new Failure();
$os->Display($fs);

//恋爱时反应
$ats=new Amativeness();
$os->Display($ats);

       适用场景及优势:     

       1) 一个对象结构包括非常多类对象。它们有不同的接口,而你想对这些对象实施一些依赖于其详细类的操作。

       2) 须要对一个对象结构中的对象进行非常多不同的而且不相关的操作。而你想避免让这些操作“污染”这些对象的类。

Visitor模式使得你能够将相关的操作集中起来定义在一个类中。

       3) 当该对象结构被非常多应用共享时,用Visitor模式让每一个应用仅包括须要用到的操作。

       4) 定义对象结构的类非常少改变。但常常须要在此结构上定义新的操作。

改变对象结构类须要重定义对全部訪问者的接口,这可能须要非常大的代价。

假设对象结构类常常改变。那么可能还是在这些类中定义这些操作较好。


欢迎关注我的视频课程。地址例如以下,谢谢。


   PHP面向对象设计模式
原文地址:https://www.cnblogs.com/mengfanrong/p/5373395.html