不,絕對沒有標準模式。
我的建議是避免新手面向對象的設計缺陷,試圖找到一個共同的「基類」接口的一切。你的龍與你的嚮導完全不同,除了可愛的代碼抽象外,試圖合併這兩個接口沒有任何好處。請記住,繼承不是代碼重用的工具。
最簡單的方法是讓每個對象保持自己的內部狀態(如前所述),並能夠繪製該狀態。這是一箇舊學校轉換語句可能比使用多態性更清晰的效果。例如:
class Dragon {
enum State { asleep, flying, breathing_fire };
public:
void draw() { /* old-school switch */
switch (cur_state){
case asleep: draw_asleep();
case flying: draw_flying();
case breathing_fire: draw_breathing_fire();
}
}
private:
void draw_asleep();
void draw_flying();
void draw_breathing_fire();
};
經驗的C++開發人員在上面的代碼喘氣(他們應該),因爲switch語句幾乎正是一個多態的方法調用將完成 - 運行時調度。 (或者更加神祕:一個方法地址表。)我個人認爲,對於這種特定類型的類,即封裝狀態機的單個公共接口,switch語句更加清晰和可維護,因爲它使得狀態機跳躍顯式。我認爲這也很明顯,我認識到這是一般不好的C++設計。
這種設計的摩擦是由狀態機和單個公共接口之間的分界線引起的。睡龍顯然不像飛龍。事實上,它幾乎沒有什麼共同之處。但更高層次的設計說,兩者是同一條龍。真是一團糟!你是否爲每個狀態創建不同的Dragon對象?不,因爲這會將國家概念暴露給調用者。你是否爲每個狀態創建不同的內部幫助對象並分派給這些對象?可能,但它很快就會變得混亂。上述方法是兩者之間的妥協。把轉換語句看作是隔離醜陋的。公共界面是乾淨的,私人界面也是如此。只有switch語句包含髒亂。考慮這種方法,並考慮其他建議。
最後,請你嚮導,你的龍,一個簡單的包裝模板或仿函數就足夠了:
struct Draw {
template <class S>
void operator()(S& s) { s.draw(); }
};
的一點是,你不必合併兩個不同的類,只是因爲他們都支持同樣的邏輯操作。
竊取現有開源遊戲的想法。 – 2010-07-24 02:18:37
std :: map - 用於內部狀態到動畫的存儲,以及任何用於外部存儲的開放格式。 –
W55tKQbuRu28Q4xv
2010-07-24 06:08:47