我正在使用装饰器模式向输出流(控制台)添加样式和选项。
这是一个控制台应用程序,可为命令行输出添加颜色。装饰师添加颜色。ClientClass中的条件是 如果发生错误则用红色文本装饰,如果没有发生错误则用绿色文本装饰。因此,颜色装饰器具有只有ClientClass 才能知道的可选调用。
* OP 对其中一个答案的评论的副本
我遇到的问题是:我通过构造函数将我的装饰器传递给一个类。但是装饰对象要求我调用两个不在基类中的方法,即被装饰的方法。
这很糟糕吗?我不应该只调用所有装饰类中可用的方法吗?
举个例子:
<?php
abstract class MyAceBaseClass
{
abstract function doYourThing();
}
class MyAceBaseClassDecoratorA extends MyAceBaseClass
{
protected $aceBaseClass;
protected $amount = 0;
public function __construct($aceBaseClass)
{
$this->_aceBaseClass = $aceBaseClass;
}
public function doYourThing()
{
$result = $aceBaseClass + $this->amount;
return $result;
}
public function decoratorFunctionA()
{
$this->amount = 10;
}
public function decoratorFunctionB()
{
//----
}
}
class ClientClass
{
private $aceObject;
public function __construct(MyAceBaseClass $aceObject)
{
$this->aceObject = $aceObject;
}
public function run()
{
if ($someCondition) {
$this->aceObject->decoratorFunctionA();
$this->aceObject->decoratorFunctionB();
}
$result = $this->aceObject->doYourThing();
echo $result;
}
}
如您所见,客户端类需要调用 decoratorFunctionA 和 decoratorFunctionB(仅在装饰器类中可用)才能调用可用于所有扩展 MyAceBaseClass 的类的抽象方法 doYourThing()。这感觉不对。
我认为装饰器的实现是正确的,但现在我遇到了另一个问题
我该如何解决这个问题?
客户端类可能不需要同时调用 decoratorFunctionA() 和 decoratorFunctionB(),它可能只需要 1 或没有,所以我不能简单地在 doYourThing 调用中自动调用它们。
一种可能性是为 MyAceBaseClassDecoratorA 提供一个接口,但是我首先违背了使用装饰器的目的。