我正面臨一個令我發瘋的嚴重設計問題。我認爲它只能用多重繼承或其他東西來解決。所以這是我想做的事:是否可以擴展對象的功能或將方法導入到PHP中的對象中?
說我有這樣定義一個基本的用戶類稱爲OrdinaryUser:
class OrdinaryUser
{
private $id,$name;
public function __construct($id)
{
$this->id = $id;
$this->name = fictionalDB::getUserNameById($id);
}
public function getName()
{
return $this->name;
}
public function getId()
{
return $this->id;
}
}
而且我有附加功能的子類,稱爲ADMINUSER:
class AdminUser extends OrdinaryUser
{
public function deleteUser($id)
{
echo "Deleting user where id=$id";
}
}
問題:如果我已經實例化了一個類型爲「OrdinaryUser」的對象並且想要將它變成一個AdminUser對象,那麼該怎麼辦?有沒有一種「擴展對象」的方法,以避免實例化子類,並且必須用相同的數據重新填充新對象的字段?
另一個相關的問題:我可能有許多其他的類別,則後面定義的用戶,每個都具有自己獨特的bahaviour,但總是一個基本的,它是沒有意義在這種情況下,因爲大多數製造等級次,一種類型的對象不應該繼承另一種類型的方法,儘管可能需要將一種類型的附加功能「導入」另一種類型的對象。
這種模式真的很棒!之前我曾聽說過這個消息,但從來沒有想過它能解決這類問題。這個解決方案正是我所需要的,謝謝!我將UserDecorator看作某種適配器,對吧?此外,我個人不喜歡使用魔法方法,但認爲__call魔術方法在這裏很合適,所以我絕對接受你的答案。所以似乎可以通過這種所謂的裝飾器模式即時添加方法並擴展對象。查爾斯的回答也很好,我很難在你和他之間做出選擇。 – fabio 2011-03-01 17:27:39
我也不喜歡使用魔術方法,但在這個實現中'__call'增加了一些不是'經典'裝飾器模式真正的一部分。在經典模式中,每個裝飾器都必須實現相同的接口並將方法調用轉發給它所包裝的對象,並可選擇對參數執行自己的操作。通過使用一點魔力,我們允許裝飾者向它包裝的對象添加新方法,並且這些方法可以從構造的外層獲得。這種靈活性非常方便,但也有其缺點,即弱化了OO合同。 – meouw 2011-03-01 20:31:58