百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>网页制作> 什么是装璜者模式,它与桥接模式有什么不一样?
分享文章到:

什么是装璜者模式,它与桥接模式有什么不一样?

发布时间:09/01 来源:未知 浏览: 关键词:

拉面的故事

拉面馆里卖拉面,拉面分为小碗和大碗,小碗一份6元,大碗一份9元。别的假如加牛肉的话,则需加6元,加一个鸡蛋是1元,加大排是5元一份,加一块锅巴是1元。假如用传统的写法,设定不一样价钱的拉面,需要写8个类(拉面份量数*配菜数)。假如此刻面馆新推一种份量——中碗,那么,就需要新增4个类。这样就会造成一个问题——类爆炸。

假如你看过我此前的文章https://www.php.cn/php-weizijiaocheng-457250.html,理解了桥接模式后,会觉得这个问题可以用桥接模式来解决。把它分为两个大类,面条和配菜。

下面我们用桥接模式来完成上述问题,代码如下:

interface INoodle
{
    function cost ();
    function desc ();
}

class BigNoodle implements INoodle
{
    private $cost = 9.0;
    private $dish = null;
    
    public function __construct(IDish $dish)
    {
        $this->dish = $dish;
    }
    
    public function cost()
    {
        return $this->cost + $this->dish->cost();
    }
    
    public function desc()
    {
        return $this->dish->desc() . '大碗拉面';
    }
}

class SmallNoodle implements INoodle
{
    private $cost = 6.0;
    private $dish = null;
    
    public function __construct(IDish $dish)
    {
        $this->dish = $dish;
    }
    
    public function cost()
    {
        return $this->cost + $this->dish->cost();
    }
    
    public function desc()
    {
        return $this->dish->desc() . '小碗拉面';
    }
}

interface IDish
{
    function cost ();
    function desc ();
}

class Beef implements IDish
{
    public function cost ()
    {
        return 6;
    }
    
    public function desc()
    {
        return '牛肉';
    }
}

class Crust implements IDish
{
    public function cost ()
    {
        return 1;
    }
    
    public function desc()
    {
        return '锅巴';
    }
}

class Egg implements IDish
{
    public function cost ()
    {
        return 1;
    }
    
    public function desc()
    {
        return '鸡蛋';
    }
}

装饰者模式

使用桥接模式确实解决了类爆炸问题,但你也知道,我们去吃面,大概有时候不要配菜,只要面,又或者我们需要多个配菜,比方,我要份大碗牛肉拉面,加3块锅巴乃至2个鸡蛋。关于这种需求,使用桥接模式是完成不了的。想要解决这种问题,我们可以借助另一种构造型设计模式——装饰者模式。

装饰模式是一种构造型设计模式, 同意你通过将对象放入包括行动的非凡封装对象中来为原对象绑定新的行动。

想要懂得装饰者模式,可以想象一个玩偶——套娃

202007081002215.jpg

每套一个娃,就相当于增加了一个装饰的对象。在运转时,会运转最外层的装饰对象(取外层的娃),然后一层一层的运转。此刻你大概不懂什么意思,看完后面的内容然后再来会看这句话或许就会清楚。

我本人画了个uml类图,有点丑,大家将就点

20200805080749.png

代码实现

abstract class Noodles
{
    abstract function cost ();
    abstract function desc ();
}

class BigNoodle extends Noodles
{
    private $cost = 9.0;
    
    public function cost()
    {
        return $this->cost;
    }
    
    public function desc()
    {
        return '大碗拉面';
    }
}

class SmallNoodle extends Noodles
{
    private $cost = 6.0;
    
    public function cost()
    {
        return $this->cost;
    }
    
    public function desc()
    {
        return  '小碗拉面';
    }
}

abstract class NoodlesDecorator extends Noodles
{
}

class Beef extends NoodlesDecorator
{
    private $desc = '牛肉';
    private $cost = 6.0;
    protected $noodles = null;
    
    public function __construct(Noodles $noodels)
    {
        $this->noodles = $noodels;
    }
    
    public function cost ()
    {
        return $this->cost + $this->noodles->cost();
    }
    
    public function desc ()
    {
        return $this->desc . $this->noodles->desc();
    }
}

// egg、curst类代码省略,除了属性值不一样根本和Beef一致

测试代码如下

$noodles = new BigNoodle();
$beefBigNoodles = new Beef($noodles);
$eggBeffBigNoodles = new Egg($beefBigNoodles);

echo $eggBeffBigNoodles->desc();
echo $eggBeffBigNoodles->cost() . '元';

结果输出:鸡蛋牛肉大碗拉面16元

总结

思索一个问题,为什么这里没有把拉面的份量作为装饰者对象?想想看,你会点一份既是大碗又是小碗的拉面吗?

装饰者模式特点

  • 装饰者和被装饰者对象有雷同的超类型

  • 可以用一个或多个装饰者包装一个对象

  • 对象可以在任何时候被装饰,所以可以在运转时动态地、不限量地用你喜爱的装饰者来装饰对象。

以上就是啥是装饰者模式,它与桥接模式有什么不一样?的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有151人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板