アレックス、多重継承が必要な場合のほとんどは、オブジェクト構造が多少不正確であることを示す信号です。あなたが概説した状況では、私はあなたが単にクラスの責任が広すぎると思います。Messageがアプリケーションビジネスモデルの一部である場合、出力のレンダリングは考慮されません。代わりに、責任を分割し、渡されたメッセージをテキストまたはhtmlバックエンドを使用して送信するMessageDispatcherを使用できます。私はあなたのコードを知りませんが、このようにそれをシミュレートさせます:
$m = new Message();
$m->type = 'text/html';
$m->from = 'John Doe <jdoe@yahoo.com>';
$m->to = 'Random Hacker <rh@gmail.com>';
$m->subject = 'Invitation email';
$m->importBody('invitation.html');
$d = new MessageDispatcher();
$d->dispatch($m);
このようにして、Messageクラスに特殊化を追加できます。
$htmlIM = new InvitationHTMLMessage(); // html type, subject and body configuration in constructor
$textIM = new InvitationTextMessage(); // text type, subject and body configuration in constructor
$d = new MessageDispatcher();
$d->dispatch($htmlIM);
$d->dispatch($textIM);
MessageDispatcherは、type
渡されたMessageオブジェクトのプロパティに応じて、HTMLまたはプレーンテキストのどちらで送信するかを決定することに注意してください。
// in MessageDispatcher class
public function dispatch(Message $m) {
if ($m->type == 'text/plain') {
$this->sendAsText($m);
} elseif ($m->type == 'text/html') {
$this->sendAsHTML($m);
} else {
throw new Exception("MIME type {$m->type} not supported");
}
}
要約すると、責任は2つのクラスに分割されます。メッセージの構成はInvitationHTMLMessage / InvitationTextMessageクラスで行われ、送信アルゴリズムはディスパッチャーに委任されます。これは戦略パターンと呼ばれます。詳細については、こちらをご覧ください。