まず、ドメインモデル(小切手、銀行など)をビュー(小切手の印刷方法)から分離します。これはMVCパターンの背後にある基本的な考え方であり、その目的の1つは、同じドメインモデルをさまざまな方法で表示できるようにすることです(これはあなたの場合のようです)。したがって、最初に次のようなドメインクラスを作成します。
class Cheque
{
protected $bank;
protected $money;
...
}
class Bank {...}
これらのクラスはMVCトライアドの「M」であり、レンダリングプロセスに関連する動作ではなく、ドメインモデルのロジックを実装することに注意してください。次のステップは、小切手をレンダリングするために使用されるViewクラスを実装することです。どのアプローチを採用するかは、レンダリングの複雑さによって大きく異なりますが、ChequeView
まず、共通部分をレンダリングし、変更可能な特定の部分(この場合は日付)を他のサブビューに委任するクラスを作成します。
abstract class ChequeView
{
protected $cheque;
protected $dateView;
public function __construct($cheque)
{
$this->cheque = $cheque;
$this->dateView = //Whatever process you use to decide if the payment date is shown or not
}
public function render()
{
$this->coreRender();
$this->dateView->render();
}
abstract protected function coreRender();
}
class BankACheckView extends ChequeView
{
protected function coreRender() {...}
}
class BankBCheckView extends ChequeView
{
protected function coreRender() {...}
}
abstract class DateView
{
abstract function render()
}
class ShowDateView extends DateView
{
function render() {...}
}
class NullDateView extends DateView
{
function render() {...}
}
また、サブクラス間で再利用するコードがある場合は、もちろんそれらを考慮に入れChequeView
てcoreRender()
呼び出すことができます。
レンダリングが複雑になりすぎる場合、このデザインは拡大縮小されない可能性があります。その場合、ビューを意味のあるサブパート(たとえばHeaderView
、AmountView
など)に分割して、チェックのレンダリングが基本的に異なるサブパートのレンダリングになるようにします。この場合、ChequeView
は基本的にコンポジットとして機能しなくなる可能性があります。最後に、このケースに到達し、セットアップChequeView
が複雑なタスクであることが判明した場合は、Builderを使用することをお勧めします。
OPコメントに基づいて編集
Builderは主に、最終オブジェクトのインスタンス化が複雑なプロセスである場合に使用されます(たとえば、一貫性のある全体を取得するためにサブパーツ間で同期するものがたくさんあります)。通常、1つのビルダークラスとさまざまなクライアントがあり、メッセージを送信して(場合によってはさまざまな順序でさまざまな引数を使用して)、さまざまな最終オブジェクトを作成します。したがって、禁止されていませんが、ビルドするオブジェクトのタイプごとに1つのビルダーを使用することは通常ありません。
特定のインスタンスの作成を表すクラスを探している場合は、ファクトリファミリーのパターンを確認することをお勧めします(おそらく、アブストラクトファクトリはあなたが考えていたものに非常に似ています)。
HTH