简单说说访问者模式的由来

在全部设计模式中,访问者模式算得上比较难理解的一种设计模式。虽然这种模式比较难理解,可是也须要去知道这种模式具体是怎么回事儿,我将从最简单的代码讲起,尝试去说说这种模式的由来。设计模式

先给定一个场景:顾客去商店买物品,购物结束后须要在收银员进行结帐。this

这里具体罗列一下几个关键词:顾客(client)、物品(goods)和收银员(cashier)设计

因而就有如下代码:code

class Cashier {
    public function checkGoods(Goods $goods) {
        echo "【Goods】Title: {$goods->title}, price: {$goods->price}";
    }
}

class Goods {
    public $title = '';
    public $price = 0;

    public function __construct($title, $price) {
        $this->title = $title;
        $this->price = $price;
    }
}

/* client */
$pencil = new Goods('铅笔', 2.5);
$cashier = new Cashier();
$cashier->checkGoods($pencil);

整体解释:继承

  1. 顾客购买一支铅笔
  2. 顾客将铅笔交给收银员结帐(checkGoods)

以上没问题,不少相似的项目也是这样设计的。宏观来讲 cashier 做为服务去结帐是没有问题的,毕竟收银员就是给客户结帐的,其实这里有点相似外观模式(Facade Pattern)。接口

那么有没有办法换一种思路去设计呢?看下面的代码:ci

class Cashier {
    public function checkGoods(Goods $goods) {
        echo "【Goods】Title: {$goods->title}, price: {$goods->price}";
    }
}

class Goods {
    public $title = '';
    public $price = 0;

    public function __construct($title, $price) {
        $this->title = $title;
        $this->price = $price;
    }

    public function checkSelf(Cashier $cashier) {
        $cashier->checkGoods($this);
    }
}

$pencil = new Goods('铅笔', 2.5);
$cashier = new Cashier();
$pencil->checkSelf($cashier);

以上代码在 Goods 中加了一个 checkSelf 方法用于接收 Cashier 实例,在 checkSelf 的这个方法中,咱们调用了实例的 checkGoods 方法。改写 client 端的代码,将不在使用 checkGoods 方法进行检查,而使用的是 checkSelf 方法将 cashier 传入 Goods 中。element

比较以上两段代码的区别,体会思惟方式,这就是访问者模式的雏形。it

接下来就是抽象了。把实例抽象化,该用接口的用接口,该用继承的用继承。io

如下就是改写上面的例子

interface IVisitor {
    public function visit(IElement $element);
}

interface IElement {
    public function accept(IVisitor $visitor);
}

class Cashier implements IVisitor {
    public function visit(IElement $element) {
        echo "【Goods】Title: {$element->title}, price: {$element->price}";
    }
}

class Goods implements IElement {
    public $title = '';
    public $price = 0;

    public function __construct($title, $price) {
        $this->title = $title;
        $this->price = $price;
    }

    public function accept(IVisitor $visitor) {
        $visitor->visit($this);
    }
}

$pencil = new Goods('铅笔', 2.5);
$cashier = new Cashier();
$pencil->accept($cashier);

这样看起来是否是可以理解很多呢?

其实设计模式没那么复杂,大部分是一种思惟方式的转变。

相关文章
相关标签/搜索