デコレータパターンを使用して、出力ストリーム(コンソール)にスタイルとオプションを追加しています。
これは、コマンドライン出力に色を追加するコンソールアプリです。デコレータが色を追加します。ClientClassの条件は、 エラーが発生した場合は赤いテキストで装飾し、エラーが発生しなかった場合は緑色のテキストで装飾することです。したがって、カラーデコレータには、ClientClassだけ が知ることができるオプションの呼び出しがあります。
*回答の1つに対するOPのコメントのコピー
私が抱えている問題はこれです:コンストラクターを介してデコレーターをクラスに渡します。しかし、装飾されたオブジェクトは、基本クラスにない2つのメソッド、つまり装飾されているメソッドを呼び出す必要があります。
これは悪いですか?すべての装飾されたクラスで利用可能なメソッドのみを呼び出すべきではありませんか?
例として:
<?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;
}
}
ご覧のとおり、クライアントクラスは、MyAceBaseClassを拡張するすべてのクラスで使用可能な抽象メソッドdoYourThing()を呼び出す前に、decoratorFunctionAとdecoratorFunctionB(デコレータクラスでのみ使用可能)を呼び出す必要があります。これは間違っていると感じます。
デコレータの実装は正しいと思いますが、今はこの他の問題で立ち往生しています
どうすればこれを解決できますか?
クライアントクラスは、decoratorFunctionA()とdecoratorFunctionB()の両方を呼び出す必要がない場合があります。必要なのは、1つだけか、まったくないため、doYourThing呼び出しでこれらを自動的に呼び出すことはできません。
MyAceBaseClassDecoratorAのインターフェイスを使用することも可能ですが、そもそもデコレータを使用するという目的に反しています。