2016-09-29 78 views
0

我想通過Repository的示例瞭解六邊形體系結構。 在這個設置中,我有以下幾層:框架(基礎結構) - >應用程序 - >域。存儲庫中的六邊形體系結構

我有User在域部分,可以說我想驗證User如果沒有任何重複通過DuplicateUsernameValidator。爲了獲得這些信息,我需要從某處獲得這些信息。我在域層再次添加了一個接口UserRepository,這樣它可以在上面的層中解決。

這是對我來說很棘手的部分。我想要實現UserRepository的邏輯,但對我來說,在應用程序層中實現這一點是沒有意義的,因爲持久化上下文位於基礎結構層(例如JdbcUserRepositoryJpaUserRepository)。 但是,如果我正確理解六角形結構,則不能直接在我的基礎結構層中實現接口UserRepository,因爲基礎結構層不應該知道域層。

我錯過了什麼?

回答

2

我認爲你所面臨的困惑來自於你試圖從六角形體系結構的角度來看待現有的三層應用程序。
讓我們來簡單吧。
讓我們暫時忘記它是什麼「應用層」。
你有你的六邊形,如果我理解正確,它包含你的應用程序的域(用戶對象)。
正確地,您正在定義一個端口在您的六邊形內,允許您從其他位置檢索用戶。 (我在說的是UserRepository接口
您的端口(JdbcUserRepositoryJpaUserRepository)的所有實現都將代表您的端口的適配器,並且應該位於您的六邊形之外,以便不會將適配器的低級別細節連接到更高級別的策略
就是這樣
可能難以理解的部分是瞭解六角形內部發生了什麼,以及不是從具有三層架構(或某種...)的應用程序開始。
保持六邊形內部什麼是與你的域名完全相關的,而不是與基礎設施相關的。
向外移動一切與外部世界相關,但不包含任何業務l邏輯。
分離並相應地移動它,一切都具有上述兩種情況。

+0

有一件事我不明白是什麼把像'JpaUserRepository'實現在基礎設施層的點。例如,'User findByName(String userName)'方法將基本實現爲'qry = em.createQuery(「從用戶u中選擇u,其中u.name =?1」); qry.setParameter(1,userName);返回qry.getSingleResult();'。它只使用領域語言和抽象基礎結構API(JPA API和JP-QL DSL)。將其置於域層中會出現什麼問題,傳統的分層體系結構就是這種情況?是不是六角矯枉過正? –

+0

當你考慮到許多真實世界的查詢不可避免地在其中嵌入業務邏輯時,它變得更加難以理解。例如:'從e選擇e從SomeEntity e其中e.status =:請求和不存在(...)'。其中一些查詢非常長,並嵌入了大量單獨的業務規則。將它們寫在域圖層外面看起來不太合適... –

+0

我不認爲它是過度的。有很多原因可以避免將基礎設施細節放入核心域。主要的是:耦合。 將數據庫代碼放在自己的適配器中的優點是什麼? 很多: - 責任分離:如果我必須改變如何從我的數據庫中檢索數據,我不必修改相對於我的業務邏輯的類/模塊; - 個人「可發展性」:例如一個開發人員可以改善查詢性能,另一個開發人員可以解決業務邏輯問題,而不會出現大問題 –

1

我想知道完全相同的問題,這裏是我的結論:您正在討論的實現是由適配器處理的。

您已將業務層開發爲六角形。好!這意味着,您的實現取決於暴露於外部的合同(= API接口)。在同樣的想法中,您的實現使用其他接口來與外部進行通信(=您稱爲UserRepository的SPI接口)。由於這些界面,您的六角形與外界隔離。 當你的六角形被實例化時,你的SPI的實際實現應該作爲參數傳遞(控制反轉)。

現在,在您的底層,您將通過實現適配器(適配器模式)來實現Jpa邏輯。

您的適配器(例如可以是Spring服務)將實現您的接口UserRepository幷包裝您的JpaUserRepository。然後,您的UserRepository中的每個方法都將被重定向到JpaUserRepository的相應方法(有或沒有一點適應)。

enter image description here