2012-02-02 41 views
1

想象一下代表一些API的一組庫。通過使用控制機制的反轉,具體實現將被注入到消耗項目中。API庫解耦方法?

這是一種情況。我有一些API庫取決於某些功能的其他API庫 - 因此,API庫本身在某些時候是耦合的。這種耦合可能會在稍後成爲問題,因爲更改一個API會導致依賴API的更改,並且相應的實現也需要更改,所以在最壞的情況下,我們會得到相當多的需要的項目修改爲僅反映其中一個變化形式。

現在我心裏有此兩種可能的解決方案:

  • 創建聯合了相關的API庫一個整體API項目。

  • 通過使每個庫爲依賴於其他API的所有功能提供接口來進一步分離API,因此直接依賴關係被移除。這可能會在兩個庫中產生類似的代碼,但是可以自由選擇通過IoC機制選擇的實現,並且還允許API相互獨立地進行改進(當API發生更改時,更改只會影響其實現庫,而不會影響其實現庫其他API或其實現)。

與第二方法的問題是代碼複製,其結果可能是有需要引用(例如太多API庫,在.NET應用程序的每個API將是一個單獨的DLL 。在某些情況下,像Silverlight應用程序,這可能是應用程序大小的問題 - 下載時間和客戶端性能)。

有沒有更好的解決方案。什麼時候將一些API庫合併成一個更大,什麼時候不合適更好?我知道這是一個非常普遍的問題,但我忽略了截止日期,估計,客戶需求和技術,我希望能夠根據實現最大可伸縮性和最小維護時間來確定正確的方法。那麼,選擇哪種方法或者您可能會建議我的另一個方法有什麼好的理由?

編輯:

我覺得我必須澄清一些有關的問題。我想到的是將API彼此解耦,而不是API的實現。因此,例如,如果我有用於驗證訪問權限的安全API以及使用(引用)安全性API的用戶帳戶API,那麼更改安全性API將需要更改用戶帳戶API以及它們的實現。碰巧以這種方式耦合的API越多,必須應用更多的更改。這是我想要避免的。

回答

4

這個選擇是在幾個巨大的圖書館和衆多的小型圖書館之間進行的。

  • 如果你有一個巨大的圖書館,代碼內將趨於緊密結合僅僅是因爲沒有提供壓力來設計一個鬆耦合的方式的各種元素的力量。風險在於它變得越來越難以發展,因爲存在如此多的相互依賴性必須協調。以.NET Base Class Library爲例。
  • 如果你有無數的小型圖書館,你可能會冒險dll地獄。是的,我們在很多年前曾承諾過這一切已經結束,但事實並非如此。試着在你的應用程序代碼庫中使用很多精細的開源庫,你就會明白我的意思了。

儘管如此,Single Responsibility Principle也適用於包級別,所以我建議小型,重點庫,而不是巨大的通用庫。這也使得總是選擇最好的庫變得更容易。

小型庫總是可以被組合/編譯成更大的庫(使用Assembly Linker/Merger/Repacker實用程序在.NET中),而拆分大型庫則更加困難。

無論你做什麼,最重要的是要記住向後兼容性。您介紹的重大更改越少,這些庫就越容易管理。

1

我不認爲這是一個問題,真的。 一些圖書館將依賴於其他圖書館,這對我來說很好:改善一個圖書館將改善所有的家屬!圖書館的「所有者」有責任在進行更改時不要破壞現有的代碼,但這是正常的,如果代碼設計良好,就可以輕鬆處理。

+0

這是真的,你說什麼。仍然處於圖書館所有者的位置,並傾向於在更多的項目中使用它們,這會在應用更改時導致事情變得非常複雜。有太多的代碼需要修改是我想避免的問題。另外,庫的版本化意味着將它們分支。找到對多個分支有效的問題會導致所有這些問題的修改,更不用說依賴項目和實施。我很樂意學習或爲減少這些努力提供建議。 – 2012-02-02 14:28:18

+0

如果你看到我的第二種方法,你可能會看到它試圖最小化更改,重構或更新的目標,但代價是額外的複雜性和可能的​​代碼重複。不過,所有相關庫的改進都將在手邊,而不需要修改所有庫。我的觀點是要儘量減少需要修改和更新的依賴關係,同時允許更改的好處影響儘可能多的應用程序。 – 2012-02-02 14:31:19

+0

我不同意,對非問題的解決方案可能會讓事情變得更加困難,因爲沒有什麼可解決的。依賴性應該通過工具來解決,或者通過「外部」而不是通過代碼解決!這不是脫鉤,它看起來像一個反模式。我的意見,當然。 – vulkanino 2012-02-02 14:40:54

1

如果你的所有依賴代碼都有變化,你應該重新考慮你的設計。如果您的庫展示某個API,則應該將其消費者與底層類或庫的更改隔離開來。


更新1:

如果應用程序使用分享幫助與API1它不應該有處理這種分享幫助使用LIB2,LIB3,..,libx中的事實。

例如Moq嘲笑庫取決於CastleDynamicProxy。你爲什麼要關心這個?你得到一個DynamicProxy已經被合併的程序集,你可以使用Moq。你永遠不會看到,使用或不得不關心DynamicProxy。所以如果DP API改變了,那不會影響你使用Moq編寫的測試。 Moq將您的代碼與底層DP的API中的更改隔離開來。

更新2:

尋找有效期超過一個分支問題導致修改它們的所有

如果這是你不建庫的情況,但一個非常具體的問題的幫手,應該在其他項目上被強制使用從不。共享庫傾向於退化爲「在遙遠未來某處可能有用」的集合。別!這會一直咬你a **!如果您有針對多個地方發生的問題的解決方案(如Guard類):請分享它。如果您認爲您可能會找到解決某個問題的解決方案:請將其留在項目中,直到您確實遇到這種情況。然後分享。千萬不要這樣做「以防萬一」。

+0

你的意思是說'API1'在'API1'中使用'API2'的地方爲'API2'的功能提供了自己的接口嗎? – 2012-02-02 14:34:58

+0

我重新考慮了我的問題,因爲我認爲這是誤導。我想根據對方來分離API,而不是API和實現。 IoC容器是最後一個容器,我永遠不會懷疑。 – 2012-02-02 14:56:17