php – Decorator模式中有什么用处?我的例子不起作用

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了php – Decorator模式中有什么用处?我的例子不起作用脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
这本书说:

我有一只兔子动物.我希望我的兔子能够拥有爬行动物的皮肤.只是想用爬行动物的皮肤装饰一只普通的兔子.

我有代码.首先,我有一个抽象类动物,每个动物都是常见的动物:

abstract class Animal {
    abstract public function setSleep($hours);
    abstract public function setEat($food);
    abstract public function getSkinType();

    /* and more methods which for sure will be implemented in any concrete animal */
}

我为我的兔子创建课程:

class Rabbit extends Animal {
    private $rest;
    private $stomach;
    private $skinType = "hair";

    public function setSleep($hours) {
        $this->rest    = $hours;
    }

    public function setFood($food) {
        $this->stomach = $food;
    }

    public function getSkinType() {
        return $this->$skinType;
    }

}

到目前为止一切正常.然后我创建了扩展Animal的抽象AnimalDecorator类:

abstract class AnimalDecorator extends Animal {
    protected $animal;

    public function __construct(Animal $animal) {
        $this->animal = $animal;
    }
}

而这里的问题来了.注意AnimalDecorator也从Animal类中获取所有抽象方法(在这个例子中只有两个但实际上可以有更多).

然后我创建了扩展AnimalDecorator的具体ReptileSkinDecorator类.它还有与Animal相同的两种抽象方法

class ReptileSkinDecorator extends AnimalDecorator {
    public function getSkinColor() {
        $skin = $this->animal->getSkinType();
        $skin = "reptile";
        return $skin;
    }
}

最后我想用爬行动物的皮肤装饰我的兔子:

$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());

但是我不能这样做,因为我在ReptileSkinDecorator类中有两个抽象方法.他们是:

abstract public function setSleep($hours);
abstract public function setEat($food);

所以,不仅仅重新装饰皮肤,我还必须重新装饰setSleep()和setEat();方法.但我不需要.

在所有书籍示例中,Animal类中始终只有一个抽象方法.当然,它的工作原理.但是在这里我只是制作了一个非常简单的现实生活示例,并尝试使用Decorator模式,如果没有在ReptileSkinDecorator类中实现这些抽象方法,它就无法工作.

这意味着如果我想使用我的例子,我必须创建一个全新的兔子,并为它实现自己的setSleep()和setEat()方法.好的,就这样吧.但后来这个全新的兔子有了commont Rabbit的例子我传给了ReptileSkinDecorator:

$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());

我在reptileSkinRabbit实例中有一个常见的兔子实例,它有自己的方法,后者又有自己的reptileSkinRabbit方法.我有兔子兔子.但我认为我没有这种可能性.

我不理解Decarator模式的正确方法.在我对这种模式的理解中,请你指出我的例子中的任何错误.

谢谢.

解决方法

听起来你正试图强迫使用不适合问题的特定模式.装饰者通常聚集一些额外的东西(向头发添加辫子),而不是完全改变它,就像你试图用皮肤(头发到鳞片).

A Builder pattern(您指定构建对象的方式)可以更好地适应问题.在你的情况下,你想要建立一个用爬行动物皮肤建造的兔子. (我来自哪里,而不是爬行动物的皮肤,制作一只有角的兔子并将其称为jackalope :)会很有趣:)

我认为在这里使用Builder(或任何模式)可能实际上是矫枉过正.你是否必须使用这种特殊问题的模式?如何定义代码如下并暂时保留模式:

class Animal {
    private $rest;
    private $stomach;
    private $skinType;

    public function setSleep($hours) {
        $this->rest    = $hours;
    }

    public function setFood($food) {
        $this->stomach = $food;
    }

    public function setSkinType($skin) {
        $this->skinType = $skin;
    }

    // define the other getters too

    public function getSkinType() {
        return $this->$skinType;
    }
}

class Rabbit extends Animal {
    public function __construct() {
        $this->rest = "rabbitRest";        // put whatever a rabbit rest is
        $this->stomach = "rabbitStomach";  // put whatever a rabbit stomach is
        $this->skinType = "hair";
    }
}

免责声明:我是一个人,我的PHP非常糟糕,我确定这个代码有几个问题,但我希望你能得到这个想法.

所以兔子只会扩展一个Animal并相应地设置它的属性.然后,如果有人想要一个RabbitReptile,他们可以扩展兔子(可能是矫枉过正)或者只是制作一只兔子并相应地设置皮肤类型.

脚本宝典总结

以上是脚本宝典为你收集整理的php – Decorator模式中有什么用处?我的例子不起作用全部内容,希望文章能够帮你解决php – Decorator模式中有什么用处?我的例子不起作用所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: