Alex, w większości przypadków dziedziczenie wielokrotne jest sygnałem, że struktura obiektu jest nieco niepoprawna. W sytuacji, którą opisałeś, widzę, że odpowiedzialność klasowa jest po prostu zbyt szeroka. Jeśli Message jest częścią modelu biznesowego aplikacji, nie powinien zajmować się renderowaniem danych wyjściowych. Zamiast tego możesz podzielić odpowiedzialność i użyć MessageDispatcher, który wysyła wiadomość przekazaną za pomocą zaplecza tekstowego lub html. Nie znam twojego kodu, ale pozwól mi to zasymulować w ten sposób:
$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);
W ten sposób możesz dodać specjalizację do klasy 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);
Zauważ, że MessageDispatcher podejmie decyzję, czy wysłać jako HTML, czy zwykły tekst, w zależności od type
właściwości przekazanej w obiekcie Message.
// 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");
}
}
Podsumowując, odpowiedzialność podzielona jest na dwie klasy. Konfiguracja wiadomości odbywa się w klasie InvitationHTMLMessage / InvitationTextMessage, a algorytm wysyłania jest delegowany do dyspozytora. Nazywa się to wzorcem strategii, więcej na ten temat możesz przeczytać tutaj .