2017-10-15 149 views
0

我有一個非常大的解決方案,由超過50個項目(Windows服務,網站,類庫)組成,使用服務框架&存儲庫並使用Telerik DataAccess ORM構建。經過與Telerik的架構師進行了長時間的討論後,他們提出了上述設計,因爲它們應該符合我們當時的需求並提供可測試的代碼框架。幾年後,現在我們的服務類已經長到數千行,使得它們更難以維護和測試。CQS文件和命名空間組織

在閱讀和研究我們的代碼中的一些問題後,我遇到了CQS(命令查詢分離),這在我們的項目中對我更有意義,因爲它會將我們龐大的服務類劃分爲更小的可測試類。我已經成功地實現了這個概念的一個小教授,但我現在想知道如何將我的代碼移動到CQS命名空間中時將我的代碼組織起來(現在將注意力集中在我想象中的命令的組織方式上) - 顯然會把所有查詢,處理程序和結果每個都在自己的文件夾中,每個文件夾都會有1000個以上的文件,這對於找到一些東西是一個巨大的麻煩。

到目前爲止,我有這個文件夾結構

Model 
     Customer 
    Queries 
     CustomerNameByIdQuery 
     CustomerNameByTextSearchQuery 
    QueryHandlers 
     CustomerNameByIdQueryHandler 
     CustomerNameByTextSearchQueryHandler 
    QueryResults 
     CustomerNameQueryResult 

兩個查詢返回的只有編號和Value屬性

現在成像我需要查詢完整的客戶記錄相同CustomerNameQueryResult也讓我將需要CustomerByIdQuery,CustomerByIdQueryHandlerCustomer型號的結果。而目前還有大約10個針對不同需求的其他用戶查詢。

數百個表中的這種模式會使很多查詢類和處理程序很難找到我需要在代碼中的特定位置使用的內容(如果可能的話,促進代碼重用)。

我正在尋找一些已經在大型生產應用程序中使用CQS的退伍軍人的建議,這些應用程序涉及項目中查詢的命名空間/文件的組織方式,以及您的解決方案是如何組織查詢/處理程序/結果的?例如,你是否將查詢&處理程序放在同一個文件中?單獨的文件是不同的目錄?你對同一個對象進行多個查詢是做什麼的?保存所有查詢或多個文件的單個文件?您是否將查詢與命名空間分開以便於編碼?您是否有任何問題與您的結構有關?

我知道這裏沒有單個「正確」的答案,但是一些人一直建議使用這種方法的人會幫助我和其他人陷入你遇到的任何問題,並在文件/文件夾結構中解決。

回答

0

我們不使用CQS,但我們有許多項目的大型解決方案,其中一個項目是存儲庫層。

我們每個模型庫類,所以以下的例子中,我們儘量讓相對客戶模式客戶庫所有查詢。實際上,這來自我們使用的圖層中的Model/Proxy/Service/Repository架構。 技巧部分帶有像聯繫人。我們有該模型,並且該存儲庫充滿了使用Contacts表的查詢。 那麼來自Customeres查詢的聯繫人在哪裏?它取決於功能性,它實際上是客戶的功能,因此它被放置在客戶信息庫中。請注意,我們可以選擇客戶,然後在循環中爲每個客戶調用聯繫人,但通常我們會避免由於性能問題。

相對於許多GetCustomerXXX方法。

是的,我們已經有很多方法,我們也有相同方法的重載,以允許使用大量不同參數進行更好的搜索,並且還有一個Paged Query Wraper,因此每次用戶滾動時都會加載一個搜索屏幕(所以我們根據你的要求改變答案)。所有這些查詢都位於客戶存儲庫中。

相對於域組織。

每個模型都可以被任何項目/域中的許多功能使用。例如,客戶位於核心域和金融域中的賬單。當然,您可以查詢客戶的所有賬單,以便客戶模型可以被任何項目/域使用。所有使用客戶和賬單的項目將具有相同的域和幾乎相同的文件夾層次結構。

簡歷: 我們有一個模型項目它被所有其他項目引用。它包含許多域和一個複雜的文件夾hyerarchy。

所有項目(服務和存儲庫除外)都引用代理項目,代理引用服務,服務引用存儲庫。

這樣我們就不會得到循環引用,管理複雜性並保持理智。 注意事項(使用代理一些UI項目,即使在不同的語言和用於實現不同的用戶體驗(網絡/ WinForm的/遠程/離線)。

編輯

有些服務可以長到像monolithc怪物。恕我直言,任何超過300線大,一些服務的數量增加最多不超過2k行。

一個因素幫了我們很多的地方已經建立的基礎類來處理最常見的情況。

例如我們HAV e存儲庫基類中的IEnumarebale<BaseModel> GetAll(GenericFilter filter)方法,這意味着所有模型都會自動實現該方法。 事實上,大部分repositoy類都是空的,因爲基本已經被覆蓋了,我們只需要編寫自定義邏輯。

此外,我們避免從另一個服務調用存儲庫,在一般服務調用服務,從而避免幾乎任何代碼重複。例如,Base Crud類具有CustomValidation方法,並且在插入/刪除/更新事件之前/之後,我們可以根據需要進行覆蓋。

繼上一個例子。客戶和聯繫人都有他們的CustomValidation。插入新客戶(通過聯繫人)將自動調用兩個驗證。

所有自動化測試調用基本方法可以節省大量時間。

+1

讓,感謝您的詳細解答。你基本上是描述我目前的架構。與此相關的「問題」在於,由於服務包含連接到相同問題域的許多不同存儲庫,因此服務會變得非常長。這就是我試圖用CQS簡化(它應該將服務分成小塊) –

+0

@DaniAvni看到我的使用基類的編輯幫助了很多工作,以最大限度地減少服務和特殊存儲庫。某些服務很複雜,服務調用其他模型服務,我們儘量避免調用其他存儲庫。 – jean

+0

Jean,我們也儘量不要從其他服務中調用服務,並且我們的大部分代碼都在工作。仍然我的服務是巨大的。例如我的任務服務具有任務的CRUD方法,任務類型的CRUD,預約任務的方法以及許多其他方法,如果我沒有記錯的話,會產生巨大的文件3K +行。這是我試圖與CQS分離的這些文件,因爲我的服務中的每種方法都會轉化爲命令或查詢,因此它應該將大文件分解成更小的可管理塊 –