MENU

PHP《设计模式》- 委托模式

April 22, 2020 • php,设计模式阅读设置

目的:

委托是对一个类的功能进行扩展和复用的方法。
简单理解一下这个概念,举个栗子:

现在有一个老干妈类,这个类有两个方法负责返回这瓶老干妈的口味、生产日期。

但是呢,有一个老爷爷年纪大了,无法看清老干妈瓶子上的字,也就无法知道这瓶老干妈的口味和生产日期。

但是恰好我们现在有一个导购员类,导购员可以描述这瓶老干妈给老爷爷听。

那么我们的老干妈类就可以委托导购员类给老爷爷描述一下这瓶老干妈!

具体代码如下

老干妈类:

/**
 * 老干妈类.
 * Class OldMother
 */
class OldMother
{

   /**
     * 定义委托的导购员属性.
     * @var shoppingGuide
     */
    private $shoppingGuide;

    public function __construct(ShoppingGuide $shoppingGuide)
    {
        $this->shoppingGuide = $shoppingGuide;
    }

    /**
     * 老干妈本身不具备描述商品信息的功能,当调用sayOldMother方法时委托ShoppingGuide类完成.
     * @param $name
     * @param $arguments
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        if (method_exists($this->shoppingGuide, $name)) {
            return $this->shoppingGuide->$name($this);
        }
    }

    /**
     * 口味.
     * @return string
     */
    public function type()
    {
        return '麻辣牛肉';
    }

    /**
     * 生产日期.
     * @return string
     */
    public function day()
    {
        return '2019/12/12';
    }

}

导购员类:

/**
 * 导购员类.
 * Class ShoppingGuide
 */
class ShoppingGuide
{

    /**
     * sayOldMother方法完成老干妈的描述功能.
     * @return string
     */
    public function sayOldMother(OldMother $oldMother)
    {
        print "这瓶老干妈的口味是:{$oldMother->type()}, 它的生产日期是:{$oldMother->day()}";
    }
    
}

测试代码:

// 将导购员的实例传递给老干妈类用于描述功能委托.
$oldMother = new OldMother(new ShoppingGuide());
// 调用描述老干妈功能方法
$oldMother->sayOldMother();

输出结果:

$[~] php OldMother.php
这瓶老干妈的口味是:麻辣牛肉, 它的生产日期是:2019/12/12

可以看到在导购员类的sayOldMother传递了一个老干妈类的实例,sayOldMother方法可以访问老干妈类实例中的方法和属性,用于播报老干妈的商品信息。

而在老干妈类的构造函数中我们传递了一个导购员的实例保存至属性$shoppingGuide,当我们在外部调用老干妈类中的sayOldMother方法时,老干妈类本身并没有这个方法,会出发__call()魔术方法,在__call()方法内我们就能委托导购员类给老爷爷描述商品信息。

Archives QR Code
QR Code for this page
Tipping QR Code