2009-09-19 81 views
0

我目前正在設計一個列表窗口小部件以添加到我的窗口小部件引擎。由於每個元素的可視方面都是在代碼外部定義的,因此我可以重用大部分代碼庫。例如標籤按鈕實際上是複選框。新模板需要時間來實現,因爲它們在設計應用程序中應該至少有一個查看器。關於列表項目及其類設計的意見

我已經有一個複選框的實現。它有2個狀態(選中/未選中)和5個子狀態:正常,懸停/活動,mousedown,禁用和狀態轉換。複選框模板具有文本屬性,圖標(可選)和邊框(可以調整大小)。還有狀態和子狀態轉換。圖標和邊框都是可以動畫的。

我的問題是關於列表項。它們與複選框非常相似。因此,我計劃使用複選框模板的listitems。但是,我需要列表項的四種模式:簡單(僅限文本),帶圖標,複選框和單選按鈕(單選按鈕源自複選框和IRadioButton界面)。這裏它的結構:

IWidgetObject 
     | 
    Checkbox  IRadioButton 
     \    /
     `--------------´ 
       | 
     RadioButton 

我希望實現這樣的東西。 ListItemBase應該從IWidgetObject派生。這是合乎邏輯還是有更好的選擇。我想隱藏ListItemBase的check()函數(爲了重命名它)。ListItemRadio將有2個不同的複選框功能,我也想隱藏ListItemBase的check()函數(重命名它)。那我應該這樣實施嗎?

class ListItemBase : private Checkbox, public IWidgetObject { 
     void Select() { do something; Checkbox::check(); } 

     //does this even works? (layer is a variable) 
     using Checkbox::layer; 
    } 

    //This listitem type will have a checkbox without any text 
    class ListItemCheckbox : public ListItemBase, private Checkbox { 
     check() { update parents checked list; Checkbox::check(); } 
    } 

    class ListItemRadio : public ListItemBase, private RadioButton, public IRadioButton { 
     //here is the problem 
    } 

但是,這一次我有2個IWidgetObjects在ListItemRadio,我要克服實現常用功能。但是ListItemBase必須將IWidgetObject的所有內容映射到複選框。

是否有可能使用虛擬繼承來解決這些問題,如委託給姐姐班(複選框)。還有一個問題,雖然IWidgetObject看起來像一個接口,但多年來,它採用了一些常見的實現,但我不認爲這會是一個問題。

還有一個問題。複選框類有不平凡的構造函數。是否可以這樣寫:

ListItemBase(IWidgetContainer &container, CheckboxBP &blueprint) : 
     Checkbox(container, blueprint), IWidgetObject(this) { 
} 

這會解決很多問題。任何想法是受歡迎的。

感謝您的閱讀,即使所有這些

回答

0

OK,我想出了一個主意

    IWidgetObject 
         | 
ICheckbox  CheckboxBase  IRadioButton 
    | \    /| \   / | 
    | `-------------´ | `---------´  | 
    |   |   |  |   | 
    | Checkbox   | RadioButton | 
    |      |     | 
    |    ListItemBase    | 
    \    |  |    /
    `---------------´  `--------------´ 
      |      | 
    ListItemCheckbox  ListItemRadioButton 

你覺得呢?

2

我不知道你的「小部件引擎」和「模板」的詳細信息,所以也許你設計,在現在迫使你的手(我希望不會!),而是一種在我看來,你在自然設計中使用繼承,而不是使用遏制和組合 - 這是一個更好的解決方案。也就是說,你說的是一個列表項「IS-A」複選框,而事務的自然狀態是列表項「HAS-A」複選框(和單選按鈕類似)。

如果你被迫通過widget引擎的設計來操作,那麼你最終需要多重繼承是不足爲奇的 - 但這會增加它自己的複雜性,並且在任何情況下,亞類導致強耦合和低靈活性,而在這些方面遏制和成分更好。我推薦閱讀經典Design Patterns,這很好地解釋了這些問題。

無論如何,如果你陷入這種設計的,那麼,是的,這可能的,就像你說的,寫的:

ListItemBase(IWidgetContainer &container, CheckboxBP &blueprint) : 
     Checkbox(container, blueprint), IWidgetObject(this) { 
} 

然而,這並不意味着該複選框基類構造函數在IWidgetObject之前執行:這取決於您聲明基礎的順序(如果您將IWidgetObject聲明爲第一個基礎,則其構造函數將在另一個之前執行)。

+0

其實沒有什麼力量是一個關係(除了它是一個可以包含的IWidgetObject),但我更喜歡那種方式。無論如何,正如你所說,保持這種設計太複雜。 –