2008年8月20日 星期三

設計模式之 Prototype 模式

以下關於Prototype模式的內容,是屬於我的理解,如果你們有不同的想法,歡迎來討論。

Prototype

上圖是設計模式的書裡頭,Prototype的架構圖。

但是我覺得這是一個容易讓人誤解的架構圖。Prototype的精神不在於架構,而在於方法,也就是那個 Clone 函式。

舉個例子,網路遊戲玩過吧,裡面有很多怪物讓你打死來練功。程式裡面,怪物是怎麼產生的?

Monster* monster=new Monster();
monster->setName("Kill Me");
monster->setHP(100);
monster->setType("Animal");
monster->setPosition(100,100);
monster->setSkill("Flee");

這樣,我們有了一隻HP 100,動物形態,名字叫做"Kill Me",會逃跑的怪物。

那麼,如果在這個場景裡面,要30隻怎麼辦? 用個迴圈,把上面的程式碼重複跑30次。但是這樣做,有點笨又沒效率。

另外一種方法就是,複製這隻怪物。在怪物類別裡增加一個Clone函式,把自己的所有屬性,包括名字,HP,形態,技能等等,都設定給複製出來的新怪物。這樣的動作,都在類別內完成,效率會比較好些,同時對於外部的應用程式來說,只需要呼叫一個 Clone 函式,哪一天如果怪物又多了個新的屬性的時候,外部應用程式是不需要修改的,只需要在怪物的 Clone 函式裡,再加上複製新屬性的程式碼就好。

Monster* Monster::Clone()
{
Monster* clony=new Monster();
clony->m_Name = m_Name;
clony->m_HP = m_HP;
clony->m_Type = m_Type;
clony->m_Position = m_Position;
clony->m_Skill = m_Skill;
return clony;
}

這隻原始的,用來複製的怪物,就是一個 Prototype。

至於最上面的那張圖,我的想法是,我們可以做一個叫做Prototype的抽象類別,裡面只有一個函式 Clone ,需要做複製的類別,可以藉由繼承 Prototype 抽象類別取得共同的介面,然後,當然,還是要實做自己的 Clone 函式。 Prototype 類別可以做為判斷可否複製之用。ConcretePrototype1, ConcretePrototype2 可以是怪物,可以是花草樹木,可以是車子,可以是八竿子打不著的物件類別,它們之所以繼承 Prototype 類別,純粹只是告訴應用程式說 -- 我這個物件是可以複製的。

沒有留言: