2010-02-03 81 views
2

我有一個類參數,其目的是爲了表示某個參數可以容納的可能值(實現兩個關鍵方法,GetNumValues()和GetValue(int index))。撰寫您繼承的類的對象?

通常一個邏輯參數(參數值是位標誌)最好由2個或更多的Parameter類實例表示(即參數可以是1或2,參數可以是4或8,而不是一個參數可以是5,6,9或10)。爲了處理這個問題,我想創建一個包含Parameters的CompositeParameter類,並且將基於它所包含的參數的組合實現GetNumValues()和GetValue()函數。

而且由於CompositeParameter組合參數使它們充當單個參數,所以「CompositeParameter是參數」關係是合理的。所以我發現自己處於這樣一種情況,即我有一個類組成它繼承的類的對象,這看起來不正確。但同時,我不明白爲什麼更高級別的代碼不應該能夠將CompositeParameters和Parameters完全相同。

我能想到的唯一選擇是讓CompositeParameter簡單地組成參數,而更高級別的代碼只會處理CompositeParameters。然而,這是有點浪費的B/C一般情況下將是僅包含一個參數的CompositeParameters。

想法?

class Parameter 
{ 
public: 
    virtual unsigned int GetNumValues() const {...} 
    virtual unsigned int GetValue(unsigned int index) const {...} 
} 

class CompositeParameter : public Parameter 
{ 
public: 
    // product of GetNumValues() of each item in mParamList 
    virtual unsigned int GetNumValues() const {...} 

    // allow all the possible combinations of the items in mParamList to be 
    // treated as one parameter. i.e. if mNumParams = 2, this would be analogous 
    // to getting the row and col index of a matrix from index, and combining 
    // the mParamList[0]->GetValue(row) and mParamList[1]->GetValue(col) 
    virtual unsigned int GetValue(unsigned int index) const {...} 

private: 

    static const unsigned int MAX_PARAMS = 10; 

    unsigned int mNumParams; 
    const Parameter* mParamList[MAX_PARAMS]; 
} 
+1

在談論C++代碼時,使用C++代碼而不是英語來描述問題幾乎總是比較好的。 – 2010-02-03 23:12:45

回答

1
I have a class which composes objects of a class it inherits from, 
which just doesn't seem right. 

這不是一個定義綜合?

(parameter values are bit flags) 

這是我會質疑的設計的一部分。也許參數的一個更好的名字是FlagSet?

將界面上的按位測試隱藏起來很好,但似乎繼承可能是矯枉過正,可以解決基礎計算機科學中衆所周知的解決方案中的問題。


However, that is somewhat wasteful b/c the general case would be 
CompositeParameters which contained just one Parameter. 

複合圖案的點是一個葉對象表示的簡單情況下,複合對象表示複雜的情況下,和客戶端代碼可以治療這兩種情況下是相同的。如果您的接口需要客戶端代碼來區分這兩者,或者遍歷基類組件,那麼您使用該模式並沒有真正獲得任何價值。

例如,如果您主要關注的是測試,然後基類可以有一個方法:

bool Test() const; 

葉類實現會是什麼樣子:

bool LeafTester::Test() { return _DoTest(); } 

複合類的實現會看起來像:

bool CompositeTester::Test() { 
    bool success = true; 

    for (int i = 0; i < m_count; i++) 
     success &= m_components[i].Test(); 

    return success; 
} 

而客戶端總是會使用這樣的代碼:

// tester could be a Composite or a leaf, but we don't care: 
bool testResult = tester.Test(); 

我已經使用for循環來保持示例簡單。在實踐中,我會使用STL。

+0

這是組合的定義,我的問題是它是從它正在編寫的同一個東西繼承而來的。 我的目標不是隱藏按位測試,而是爲了測試目的創建一些能夠生成所有可能值的東西。這是GetValue(...)的結果,將用於按位測試。 我只是使用名稱參數來說明,我真正的問題是關於組成/繼承設計。 – Chris 2010-02-04 00:28:01

+0

組合的定義是它繼承了它與它組合的相同事物。請參閱「設計模式」pp164。如果這就是你的組合所做的,那麼它就遵循這個模式。 – richj 2010-02-04 09:33:20

+0

根據模式,Composite和Leaf都來自抽象基類Component。所以如果你想按照本書所描述的方式來實現這個模式,參數將是抽象的,你需要第二個子類LeafParameter。 – richj 2010-02-04 09:42:29

2

這似乎是一個完全合理的設計。我所做的唯一改變是將參數從一個類改爲一個接口。

然後你可以有一個參數類(或者一個ParameterImpl類)實現的參數,也有CompositeParameter類,也實現了參數接口

+0

因此,CompositeParameter將實現Parameter接口幷包含ParameterImpl對象? – Chris 2010-02-03 23:33:02

+0

是的,那個或任何實現了參數接口的對象 – 2010-02-03 23:35:41