2010-09-23 63 views
3

我的C++應用程序的很大一部分使用類來描述數據模型,例如,就像ClassType(它實際上模仿純C++中的反射)。保持模塊獨立,同時仍然彼此使用

我想向我的應用程序添加一個新模塊,它需要使用這些ClassType,但我不希望從ClassType的新模塊引入依賴項。

到目前爲止,我有以下選擇:

  • 沒有把它獨立和引進上一類類別的依賴,在我的應用程序中創建更多的「spaghetti'依賴性的風險(這是我最偏愛的解決方案)
  • 引入一個新類,例如IType,並讓我的模塊只依賴於IType。 ClassType應該從IType繼承。
  • 使用字符串作爲標識方法,並強制新模塊的用戶將ClassType轉換爲字符串,反之亦然。
  • 使用GUID的(甚至是簡單的整數)作爲標識,還需要GUID的之間的轉換類類別的

你應該多遠嘗試在應用程序中去耦模塊時候去?

  • 只是介紹一個接口,讓所有其他模塊依靠接口? (如上面描述的IType)
  • 甚至通過使用其他標識,如字符串或GUID的進一步解耦它?

我擔心,通過將它解耦太多,代碼變得更加不穩定並且更難調試。我在Qt中看到了一個這樣的例子:信號和插槽使用字符串鏈接,如果你輸入錯誤,功能不起作用,但它仍然編譯。

您應該將模塊隔離多遠?

回答

1

我會避開關於思考的思考,只是看看依賴性思想。

解耦合理解耦。耦合意味着如果有一件事發生了變化,那麼另一件事情就必須改變因此,你的NewCode使用ClassType,如果它的某些方面發生變化,那麼肯定必須更改NewCode - 它不能完全解耦。你想從哪個方面解耦?

  1. 語義,ClassType是做什麼的。
  2. 接口,你怎麼稱呼它。
  3. 實現,它是如何實現的。

在我看來,前兩個是合理的耦合。但是,實施變更當然不應該要求NewCode進行更改。所以代碼到接口。我們試圖保持接口的固定,我們傾向於擴展它們而不是改變它們,如果可能的話保持它們的兼容性。有時我們使用名稱/值對來嘗試使界面變得可擴展,然後點擊您提到的錯誤類型錯誤。這是靈活性和「型號安全性」之間的折衷。

2

99%的時間,如果你的設計是基於反思,那麼你有設計的重大問題。

一般來說,像

if (x is myclass) 
elseif (x is anotherclass) 
else 

東西是一個糟糕的設計,因爲它忽視了多態性。如果你這樣做,那麼項目x違反了Liskov替代原則。

另外,考慮到C++已經有RTTI,我不明白你爲什麼要重新發明輪子。這就是typeofdynamic_cast

+1

完全同意。重新創建RTTI幾乎總是背叛了對C++ OOP基本缺乏理解。 – Reinderien 2010-09-23 17:32:59

+0

我有充分的理由使用基於反射的設計,因爲我的應用程序有些特別。使用配置文件,用戶可以使用其他類型和屬性擴展數據模型。如果沒有基於反射的設計,這是不可能實現的,並且C++的RTTI在這裏也沒有幫助。如果不是這種靈活性,我完全同意你的看法。不幸的是,在這種情況下,我不能。 – Patrick 2010-09-23 18:50:47

+1

@Patrick:如果你使用的類型是動態的,那麼無論如何你都不能用C++類型來實現你的類型系統。你最好用一個'UserType'類型,它可以包含子'UserType's,然後用戶可以擴展。 – 2010-09-23 19:22:41

0

這是一個哲學問題;它取決於模塊的類型和折衷。我想我已經在不同的時間親自完成了所有這些工作,除了GUID類型映射外,在我看來,這對字符串類型映射沒有任何優勢,並且至少字符串是可讀的。

我會說你需要看看特定模塊需要什麼級別的解耦,給定預期的外部使用和代碼組織,然後從那裏開始。就我所知,你已經達到了所有的概念方法,並且在特定情況下它們都是有用的。

這是我的意見,無論如何。

相關問題