[翻譯]在 Go 應用中使用簡明架構(2)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

原文在此,續前……

——–翻譯分隔線——–

在 Go 應用中使用簡明架構(2)

架構實現

首先來實現領域層。之前已經說過,應用和其用例將完全可用,但是這不是一個完整的商城。因此,定義領域的代碼應當足夠短小,這樣正好可以放在一個檔案中:

package domainimport ("errors")type CustomerRepository interface {Store(customer Customer) errorFindById(id int) Customer}type ItemRepository interface {Store(item Item) errorFindById(id int) Item}type OrderRepository interface {Store(order Order) errorFindById(id int) Order}type Customer struct {Id   intName string}type Item struct {Id        intName      stringValue     float64Available bool}type Order struct {Id       intCustomer CustomerItems    []Item}func (order *Order) Add(item Item) error {if !item.Available {return errors.New("Cannot add unavailable items to order")}if order.value() + item.Value > 250.00 {return errors.New(`An order may not exceed                   a total value of $250.00`)}order.Items = append(order.Items, item)return nil}func (order *Order) value() float64 {sum := 0.0for i := range order.Items {sum = sum + order.Items[i].Value}return sum}

顯而易見,這段代碼沒有重度依賴任何東西,除了為了某些方法返回錯誤,而引入了“errors”包。儘管這裡描述的領域模型最終將以行的形式存在於資料庫中,但這裡卻沒有任何資料庫相關的代碼。

我們定義了三個所謂用於儲存區的 Go 介面作為替代。儲存區是來自領域驅動設計的一個概念:它將領域模型的儲存和載入從某種持久化機制中抽象出來。從領域的角度來看,儲存區僅僅是一個用於擷取(FindById)或盛放(Store)領域模型的容器。

CustomerRepository,ItemRepository 和 OrderRepository 僅僅是介面。由於它們是資料庫和應用之間的介面,所以將在介面層實現。這裡說明了如何將依賴原則應用於 Go 應用:內部層定義的抽象介面不引用任何外部層的東西;其實現定義在外部層中。這樣實現就可以注入到想要使用它的層中去;在一會就能夠瞭解到,這個例子中,就是應用在用例層。

通過這種方法,用例層可以使用領域層的表達方式,來引用領域層的概念——儲存區。同時,實際執行的代碼卻是在介面層。

對於每層的每個部分來說,有三個有趣的問題:它用在哪;它的介面在哪;它的實現在哪?

就 OrderRepository 舉例來說,答案如下:它將被用在用例層,它的介面屬於領域層,它的實現屬於介面層。

從另一個方面來說,Order 實體的 Add 方法是用例層使用的,並且同樣的其介面屬於領域層。但是它的實現也在領域層,因為它自身並不需要任何領域層外部的東西。

有三個結構會實現儲存區介面的定義:Custormer、Order 和 Item。它們代表了三個領域模型。Order 實體通過兩個方法 AddItem 和 value 實現了一些額外的功能,後者僅僅是一個內部使用的協助函數。AddItem 實現了用例需要的特定領域功能。

在討論整體架構的時候,這段代碼裡還有一些額外的細節與此相關。如同你已經瞭解的,我們為 AddItem 方法添加了一些約束條件。很快就會發現,我們的應用會在若干個地方有若干個約束條件,討論哪個約束條件屬於哪裡是很有趣的。

第一個約束條件是不允許添加一個停用商品到訂單——很明顯這是一個商業約束。不允許使用者對停用商品下訂單這一約束條件,對於Web 商店和電話熱線的訂購是一樣的;這並不是(我們的)軟體特有的東西——定義這個約束條件是商業頭腦驅使的。

訂單總額不能超過 $250 的約束也是一樣的——不論商店是個網站還是個案頭遊戲,這就是總是有效商業規則。

其他約束條件在別的一些地方——某些地方,商品的值必須儲存在資料庫,那麼就必須對資料庫中 value 欄位儲存的浮點數額外小心;然而這是一個技術約束條件,而不是一個商業約束條件,那麼就不屬於領域包。

另一方面來說,資料庫介面代碼和資料庫本身在持久化總額超過 $250 的訂單時,完全無需擔心這點,它們可以很好的遵從這個商業規則。這個例子對於 Bob 大叔的理念是一個很有力的說明,比如說做一個完全相反的假設:例如將 $250 的訂單限制條件添加在資料庫的預存程序中。一旦你的應用開始增長,那就祝願你所有的商業規則都還能保持完整吧。我更樂意在任何時候,都保持它們在相同的地方。

——–翻譯分隔線——–

未完待續……

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.