Алекс, більшість випадків, коли тобі потрібно багатократне успадкування - це сигнал, що ваша об'єктна структура дещо неправильна. У ситуації, яку ви окреслили, я бачу, що у вас класова відповідальність просто занадто широка. Якщо Повідомлення є частиною бізнес-моделі програми, воно не повинно піклуватися про надання виводу. Натомість ви можете розділити відповідальність та використовувати MessageDispatcher, який надсилає повідомлення, передане за допомогою тексту чи html-сервера. Я не знаю вашого коду, але дозвольте змоделювати його таким чином:
$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);
Таким чином ви можете додати певну спеціалізацію до класу повідомлень:
$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 буде приймати рішення про те, чи надсилати у форматі HTML або звичайний текст залежно від type
властивості в об'єкті повідомлення.
// 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");
}
}
Підсумовуючи це, відповідальність розподіляється між двома класами. Конфігурація повідомлення здійснюється в класі InvitationHTMLMessage / InvitationTextMessage, а алгоритм відправки передається диспетчеру. Це називається стратегічний шаблон, докладніше про нього можна прочитати тут .