2013-03-13 68 views
2

我正在使用C#爲我們的應用程序構建一個公共API。我有一組與WCF客戶端一起使用的DTOs外觀類。它允許API消費者從數據庫應用程序中獲取,更新,創建等等。標準材料:客戶擁有訂單集合,訂單中包含行項目集合等。不允許任意實現時使用接口隱藏實現細節

外觀類都來自公共基類,並覆蓋驗證,讀取/寫入DTO和其他管道的方法東西,全部使用各種內部類型。我正在使用工廠創建新對象並獲取現有對象。

現在的問題是如何最好地通過API公開類,同時最大限度地減少實現細節的暴露。

接口看起來像是一種明顯的方法,因爲它是限制暴露內容的最簡單方法(並且最終可能是必需的,因爲COM兼容接口正在考慮之中)。接口方法的問題是內部我的代碼將取決於接口的特定實現。

假設我有一個ICustomer接口暴露了我的CustomerFacade,IOrder暴露了OrderFacade。在外部,ICustomer擁有一系列IOrders。但在內部,CustomerFacade有一個OrderFacades集合。如果客戶端應用程序向客戶添加一個新的IOrder,我必須檢查IOrder是否真的是一個先前從我的工廠創建的OrderFacade,而不是我的控制之外實現IOrder的其他對象。那是因爲在內部,我需要一個能夠比IOrder做得更多的命令。

實際上,這並不重要 - API的用戶不會嘗試創建自己的Order實現。但對我來說,這感覺不雅,就像濫用界面合同應該是什麼意思一樣。

直接暴露外觀類並不是很好,因爲整個類層次結構必須暴露,以及受保護方法使用的內部類型,並且使用消費者不會使用的類型將API混淆並不需要知道。

我能想到的另一種選擇是另一層封裝:一個訂單包含一個私有的OrderFacade,並且只公開應該公開的成員。但是這看起來像是很多額外的代碼來獲得有限的好處。

我認爲是抽象基類,但由於繼承結構的原因,這並不比暴露外觀類更好。例如,如果我有一個從CatalogItem繼承的ServiceItem,在它們之間引入一個抽象的ServiceItemBase仍然需要我公開CatalogItem中的所有受保護的方法。

對這些方法的任何建議,或者我沒有看過的替代方案?

+2

您始終可以將OrderFacade實現爲可用OrderId構造,並且完全忽略接口。您的客戶不會重塑您的訂單工作方式,他們只想輸入數字並獲得答案。看一下微軟自己的C#API--很少有接口,它們只在需要的時候纔出現,比如COM,而且你仍然不知道或者不在乎它們是如何工作的。所有你想要的是給Word API一個文件名並獲得一個Word文檔,而不是自己實現IDocument – 2013-03-13 14:27:23

+0

@StenPetrov謝謝,但我不明白這是如何解決如何最好地隱藏內部細節我不知道不想泄漏到API中。 – William 2013-03-13 16:24:29

+0

你已經有了服務 - 這就是大多數(如果不是全部的話)魔術應該發生的地方。 API的客戶端應主要用於調用服務(驗證,配置處理等)。我所說的並不是跳入抽象的過程(界面,抽象類,工廠等)。 – 2013-03-13 16:53:42

回答

0

這似乎很複雜。我不知道你想解決的業務問題,所以我不知道爲什麼需要各種外牆。如果用戶將使用您的api進行數據操作,您可以考慮使用命令修改數據,並查詢返回僅包含客戶端所需數據的DTO。

http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613

這是一個偉大的書,可能的幫助。

+0

看起來像一個很好的參考。我會看看是否有什麼我可以申請的東西。 – William 2013-03-13 16:37:44

0

您也可以使用公共構造函數而不是接口公開構造函數暴露抽象類。這還有另外一個好處,就是抽象類可以作爲一個不間斷的變化來擴展,這對於接口來說是不正確的。

使用內部訪問修飾符可以隱藏不應該在實現程序集中可見的成員。

+0

我應該在問題中提到該選項;我已更新以解決這個問題。抽象基礎在我這裏不起作用,因爲它們仍然繼承自其上面的類(並因此暴露了受保護的成員)。 – William 2013-03-13 16:34:19

+0

這不就是爲什麼提供內部訪問修飾符? – 2013-03-13 16:36:30

+0

好點。我可以將所有受保護的成員更改爲內部。這暴露了大會之外的一些事情,但在這種情況下這不是一個大問題。 – William 2013-03-13 17:45:32