2014-07-02 55 views
-1

哪種方法最適合建築設計?這兩者之間的折衷是什麼?還有其他解決方案嗎? 我需要使用多態性來對待RecordBlockReader和PositionBlockReader。 (從InputBS繼承)建築設計之間的權衡

樣本1 - 型鑄造:

class IDataBlock{ 
public: 
    virtual void method1() = 0; 
} 

class RecordBlock: public IDataBlock{ 
public: 
    virtual void method01(){/* code */ }; 
    void method02(){ /* code */ }; 
} 

class PositionBlock: public IDataBlock{ 
public: 
    virtual void method01(){/* code */ }; 
    void method03(){ /* code */ }; 
} 

class InputBS{ 
public: 
    virtual IDataBlock * getNext() = 0; 
} 

class PositionBlockReader: public InputBS{ 
public: 
    virtual IDataBlock *getNext(){ return new PositionBlock(); } 
} 

class RecordBlockReader: public InputBS{ 
public: 
    virtual IDataBlock *getNext(){ return new RecordBlock(); } 
} 

//Client Code 
InputBS *recordBlockReader = new RecordBlockReader(); 
RecordBlock *recordblock = static_cast<RecordBlock *>(recordBlockReader->getNext()); 
recordblock->method02(); 

InputBS *positionBlockReader = new PositionBlockReader(); 
PositionBlock *positionBlock= static_cast<PositionBlock *>(positionBlockReader->getNext()); 
positionBlock->method03(); 

樣品2 - 使用 「胖」 接口:

class IDataBlock{ 
public: 
    virtual void method1() = 0; 
    virtual void method2() = 0; 
    virtual void method3() = 0; 
} 

class RecordBlock: public IDataBlock{ 
public: 
    virtual void method01(){/* code */ }; 
    virtual void method02(){ /* code */ }; 
    virtual void method03(){ /*throw exception not_supported_operation*/ }; 
} 

class PositionBlock: public IDataBlock{ 
public: 
    virtual void method01(){/* code */ }; 
    virtual void method02(){ /*throw exception not_supported_operation*/ }; 
    virtual void method03(){ /* code */ }; 
} 

class InputBS{ 
public: 
    virtual IDataBlock * getNext() = 0; 
} 

class PositionBlockReader: public InputBS{ 
public: 
    virtual IDataBlock *getNext(){ return new PositionBlock(); } 
} 

class RecordBlockReader: public InputBS{ 
public: 
    virtual IDataBlock *getNext(){ return new RecordBlock(); } 
} 

//Client Code 
InputBS *recordBlockReader = new RecordBlockReader(); 
IDatablock *recordblock = recordBlockReader->getNext(); 
recordblock->method02(); 

InputBS *positionBlockReader = new PositionBlockReader(); 
IDatablock *positionBlock= positionBlockReader->getNext(); 
positionBlock->method03(); 

回答

1

「在繼承青睞組成」 現在這兩項設計採取類似行動,但傳達不同類別之間的關係。

在第一個例子,是RecordBlock在內的數據塊也可以做方法2.

在第二,RecordBlock是一個數據塊,因此它可以做方法1,2,和3中,但這將是一個錯誤它試圖做方法3.

通常,如果一個方法只會拋出一個不受支持的異常,你應該重新考慮你的設計。所以我會選擇第一個策略。但是,如果你可以使用組合做到這一點。當您嘗試稍後重構代碼時,它將爲您節省很多麻煩。

我真的推薦閱讀Effective C++,它是一個很棒的閱讀,並且深入探討了很多這樣的話題。

+0

我知道java集合實現了第二個選項,拋出異常不支持的操作... –

+0

你會如何使用這個例子中的組合? –

0

我肯定會去爲你建議的兩個前解決方案。

但是我有些困惑,爲什麼在這種情況下你需要繼承 - 也許這個例子很糟糕,但是如果你「需要知道它使用哪種類型」,那麼你可能正在做一些事情在你的課堂/對象設計中是錯誤的。當代碼使用錯誤的方式使用對象時拋出一個異常並沒有什麼好處 - 你希望編譯器告訴你...

當然,有些時候這是正確的(我的抽象語法樹編譯器肯定有你需要知道什麼是類的地方 - 但這是20-30個類,所有這些類都代表了程序的不同部分,而「for-loop」與其中的「if-語句「,它與」函數「等不同 - 但是實際的代碼生成階段的主循環實際上並不需要知道什麼類是一切 - 有時在不同對象的代碼中「這是一個這樣的對象,還是其他類型」)有點混亂。