Alex, hầu hết các trường hợp bạn cần đa kế thừa là một dấu hiệu cho thấy cấu trúc đối tượng của bạn có phần không chính xác. Trong tình huống bạn nêu ra, tôi thấy bạn có trách nhiệm trong lớp đơn giản là quá rộng. Nếu Message là một phần của mô hình kinh doanh ứng dụng, thì nó không nên quan tâm đến kết xuất đầu ra. Thay vào đó, bạn có thể phân chia trách nhiệm và sử dụng MessageDispatcher để gửi Thông báo được chuyển bằng văn bản hoặc chương trình phụ trợ html. Tôi không biết mã của bạn, nhưng hãy để tôi mô phỏng nó theo cách này:
$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);
Bằng cách này, bạn có thể thêm một số chuyên môn vào lớp 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);
Lưu ý rằng MessageDispatcher sẽ đưa ra quyết định gửi dưới dạng HTML hay văn bản thuần túy tùy thuộc vào thuộc type
tính trong đối tượng Message được truyền.
// 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");
}
}
Tóm lại, trách nhiệm được phân chia giữa hai lớp. Cấu hình thông báo được thực hiện trong lớp InvitationHTMLMessage / InvitationTextMessage và thuật toán gửi được ủy quyền cho người điều phối. Đây được gọi là Mô hình Chiến lược, bạn có thể đọc thêm tại đây .