1

我一直在試圖理解這種新的架構,其名稱可以是洋蔥架構,乾淨的架構,端口和適配器等。在洋蔥式架構中,實體是否應該穿過外層?

如果我把端口和適配器的抽象,當我適應我的應用程序一個特定的端口,我可以給我的應用程序內的端口一個實體嗎?還是我總是應該調整實體,以適應端口?

例如:

說我有一個客戶實體。我有一個使用我的應用程序的用戶界面。我的UI通過Adapter調用getCustomerById(123)。接下來,我的適配器會調用我的應用程序,使用注入的Repository有效地檢索客戶,並且它將對其執行某種格式化操作並記錄,並且一旦客戶準備好就返回到我的用戶界面。我的問題在於,我的Customer對象返回給我的用戶界面。這意味着我的UI具有對Core項目中的Customer類的引用。然後,我的用戶界面繼續使用該客戶對象來做事情,也許改變它的名字等,並最終再次調用適配器到updateCustomer(客戶)。

這可以嗎?我的UI在應用程序內核中使用Customer類是否可以。還是應該讓我的客戶適應一個新的客戶對象,比如說UICustomer,並讓我的用戶界面能夠與之一起工作,在客戶和UICustomer之間在適配器級別來回映射?

回答

1

偉大的問題。我有一個可能有用的例子。 https://bitbucket.org/jeffreypalermo/onion-architecture

對於使用核心域模型對象的簡單應用程序可以很好。這些設計的目的不是讓它們掛着依賴的令人討厭的觸手,所以它們工作得很好,而且非常便攜。他們可以穿越圖層而不會造成任何問題。

+0

謝謝你分享這個回購。它真的爲我回答了一堆問題,但我仍然有一個大問題。你會在哪裏進行業務邏輯/數據有效性檢查?我假設它將在VisitorProcessor中。我對麼? – jgriffin

+0

我在你的例子中看到領域模型是貧血的。看起來您將域邏輯放入Processor類中,但我不確定這是故意還是因爲您的域模型太簡單,並且不需要任何邏輯,並且Processor類是您的服務層。這是我的問題,如果我有一個貧血的領域模型,因此,一個簡單的沒有行爲,我明白,它更容易與UI共享,但如果我有一個複雜的領域模型與很多行爲和深層嵌套的關係,我還應該在我的用戶界面中使用它嗎? –

+0

@jgriffin,數據有效性可以分爲兩種類型。 1)數據類型,2)操作的業務適用性。用嚴格的鍵入來定義你的模型,以確保只有符合類型的數據才能進入。例如,如果你不想使用負數或者不想使用大數字,我們可以使用ushort而不是int數。然後使用外部業務邏輯或規則模式來檢查模型是否對某個特定操作或要調用的命令「有效」。 –

1

我也開始學習/實施洋蔥建築。從我所知道的,你原來的方法(用戶界面中的客戶實體)是一種可接受的做法。看看這裏的洋蔥架構的圖形,直線,表示:

http://jeffreypalermo.com/blog/the-onion-architecture-part-3/

你可以看到,用戶界面可以與下面的對象模型直接交互。由於您的客戶不是直接的數據庫實體,而是從注入的存儲庫加載,這似乎符合洋蔥的模型。

這裏我的假設是客戶實體實際上是通過注入存儲庫彙編的不同規範化DB實體的組合。

我的理解是,原則上,交互是通過抽象來完成的,事實上客戶實體是客戶數據庫的抽象表示,這是有效的。

請糾正我,如果任何上述假設/想法不正確。

+0

我的問題是,如果我這樣做,我創建了從我的用戶界面到我的實體的依賴關係。現在,說我正在研究我的洋蔥核心,完善我的領域模型,在他們身上添加新的行爲,重構我的實體的屬性,可能會將名稱分解爲第一個和最後一個例子,並進行一系列其他更好的更改就我的核心而言。這些更改可能會破壞用戶界面,因爲實體可能已經更改爲更多。我需要去更新我的用戶界面來代替使用新實體。 –

+0

我的第二個問題是,也許我的UI會突然需要對我的實體有特殊需求。假設它必須大寫名稱字段,因爲格式化約束對於我的用戶界面是唯一的。我會去我的實體上添加一個UpperCaseName字段嗎?如果我這樣做,我會將UI滲透到核心中。因此,這個問題和上面的問題都會影響到我可能不會更改實體,因爲它會破壞UI,或者由於UI需要的需求,我可能會更改實體。 –

+0

我的存儲庫是抽象的,因爲在我的核心中,它只是一個接口,但在外部,它成爲一個實現。但是我的實體並不是抽象的,因爲在我的核心中,它們是數據和行爲的實現。如果我在外部重新實現了實體,那麼通過製作一個特定於我的UI要求的客戶,並將我的核心客戶映射到我的UI客戶,這更類似於正在使用Repository進行的操作。它的缺點是,在大多數情況下,兩個Customer對象可能實際上是相同的。所以我不確定這是值得的努力和時間。 –