2016-12-07 31 views
1

我有時會遇到,主要是在使用舊代碼時,一個類只能將調用轉發給另一個類。想象一下,有一個老的控制器可以控制某些東西,但其中一些控制器可以用於一個新的類。現在,舊的控制器將調用新的類接口。類接口複製

Ex。

class Controller { 
    public: 
    void addObject(const std::string & id, 
     const Object * obj) { 
     m_Wrk.addObject(id, obj); 
    } 
    private: 
    Worker m_Wrk; 
}; 

class Worker { 
    public: 
    void addObject(const std::string & id, 
     const Object * obj) { 
     //do actual adding 
    } 
}; 

現在,想着測試軟件時,接口可能需要在這兩個班進行測試,因爲它並不主要是因爲它是必要的檢查控制器的測試工作人員的變化是在控制器更難。

這種用法特別糟糕,還是可以在上面解釋的現有代碼中使用這種設計。

感謝

+1

我說的'm_Wrk'應該是一個指針嗎? – alexeykuzmin0

+0

錯字。它並不一定需要。 –

+0

這實質上不是PIMPL。我想我很難理解這個問題。您能否重新說明這一點: 現在,在考慮測試軟件時,可能需要在兩個類中測試接口,並且它在控制器中比較困難,因爲它並不主要,因爲它需要檢查工作人員更改控制器測試。 這種用法特別糟糕,或者可以在上面解釋的已有代碼中使用這種設計。 – SmittyBoy

回答

0

很難回答這個代碼是好還是壞的 - 這取決於環境。有問題的代碼(除了m_Wrk字段應該是指針這一事實)是PImpl模式,這是一種bridge模式。這種模式被用來分離抽象和實現,以便它們可以獨立地改變。例如,如果你編寫一個C++庫,並且你希望提供一個穩定的ABI,如果公共接口沒有變化就不會改變,你可以將Controller接口放在頭中,聲明Worker類,並將Worker的接口和實現都放在.cpp文件中。 Worker更改時,Controller ABI保持不變。如果實施細節直接放在Controller類中,則ABI可能會發生變化。另外,這樣的模式(Bridge一般而言)允許你使用不同的抽象實現,因此,就Liskov替換而言,可以根據接口擴展和繼承分離繼承。

此外,如果Controller實現與Worker相同的接口,將來它可以實現一些附加行爲,如proxy模式。

如果其中一種情況發生在您的項目中(或將來可能發生),那麼這可能是一個很好的代碼。如果不是,這只是一個不必要的複雜。