走向.NET架構設計—第四章—業務層分層架構(中篇)
前言: 在上一篇文章中,我們讨論了兩種組織業務邏輯的模式:Transaction Script和Active Record。在本篇中開始講述Domain Model和Anemic Model。
注:不管技術的道路多麼難走,我們還是得踏踏實實的把技術做下去。也希望朋友們能夠一如既往的支援本系列。
本篇議題如下: Transaction Scrip(前篇) Active Record前篇) Domain Model(中篇) Anemic Model(後篇) DDD(後篇)
Domain Model:
在開發過程中,我們常常用Domain Model來對目标的業務領域模組化。通過Domain Model模組化的業務類代表了目标領域中的一些概念。而且,我們會看到通過Domain Model模組化的一些對象模拟了業務活動中的資料,有的對象還反映了一些業務規則。
我們就來看看電子商務系統的開發,在開發中我們建立了一些概念的模型來反映電子商務領域中的一些概念:購物車,訂單,訂單項等。這些模型有自己的資料,行為。例如一個訂單模型,它不僅僅包含一些屬性(流水号,建立日期,狀态)來包含自己的資料,同時它也包含了一些業務邏輯:下訂單的使用者時候合法,下訂單使用者的餘額是否充足等。
一般來說,我們對領域了解的越深,我們在軟體中建立的模式越接近現實中的概念,最後實作的軟體就越符合客戶的需求。同時在模組化的過程中,也要考慮模型的可實作行,可能我們對領域進行了很好的模組化,和符合目标領域的一些概念,但是在軟體實作起來非常的困難,那麼就得權衡一下:找出一個比較好的模式,同時也便于實作。
在以前的文章中其實也提到過一些有關Domain Model的一些東西,其實Domain Model和Active Record的一個差別在于:Domain Model不知道自己的資料時如何持久化的,即PI(Persistence Ignorance).也就是說,通過Domain Model建立的業務類,都是POCO(Plain Old Common Runtime Object)。
建立一個新的解決方案,命名為ASPPatterns.Chap4.DomainModel,并且添加如下的項目:
下面就來看看每個項目代表的含義:
其中:
q AgileSharp.Chapter4.DomainModel.Model:業務層,在這個類庫項目中包含了系統中所有的業務邏輯和業務對象,以及業務對象之間的關系。這個項目也定義了持久化領域對象的接口,并且是用Repository 模式來實作的(Repository 這個模式我們後面會談到)。這個Model層沒有對其他的類庫項目進行引用,完全關注于業務。
q AgileSharp.Chapter4.DomainModel.Repository:這個Repository的類庫項目實作了在Model 類庫中定義的持久化接口。Repository對Model 類庫項目進行了引用。
q AgileSharp.Chapter4.DomainModel.Infrastructure:提供輔助功能,例如發送郵件,記錄日志等。
q AgileSharp.Chapter4.DomainModel.Contact:包含資料契約和服務契約。
q AgileSharp.Chapter4.DomainModel.Service:服務層,實作契約層提供的服務接口,并且通過Web Service接口向外界暴露服務。
q AgileSharp.Chapter4.DomainModel.WCFHost:WCF宿主程式。
q AgileSharp.Chapter4.DomainModel.WPFUI:主要是負責最後的顯示邏輯和一些使用者體驗的實作。這個類庫調用服務層提供的API,來送出請求和顯示結果。
很多時候可以根據業務模型設計出資料模型(例如,資料表),然後采用相應的政策,并遵循一定的規則,來確定對資料進行高效存取(有關資料模型和領域模型的相關話題,在本書第7章的“領域模型 VS. 邏輯模型”一節會詳細講述)。此處,領域模型比較簡單,對應的資料模型的結構基本和領域模型一樣,但是在很多的系統中,領域模型和資料模型是不一樣的,例如,一個業務模型的資料要來自于多個資料模型。
下面首先建立Order領域類,如下所示:
public class Order
{
public string OrderNo { get; set; }
public OrderStatus Status { get; set; }
public List<OrderItem> Items { get; set; }
//計算訂單的總價
public decimal CaculateTotalPrice()
{
decimal result = 0;
if (this.Items != null && this.Items.Count > 0)
{
result = this.Items.Sum(u => u.Products.Sum(p => p.Price));
}
return result;
}
//檢查訂單的狀态,判斷訂單是否已經被處理
public bool CheckStatus()
return this.Status != OrderStatus.Processed;
}
public enum OrderStatus
{
New,
Processed
}
}
正如之前所講:每個業務類隻關注自身的業務,而每個流程又是多個業務類和其他一些輔助類組合完成的,很多的時候都會在領域層中加入服務類,形成很“薄”的服務層(也稱為應用層)。下面我們來讨論一下有關服務層的話題(本書的第5章将對服務層進行深入讨論)。
處理領域邏輯常見的方法是将領域層(也稱“業務層”)細分為兩層:在領域層中把服務類獨立出來,作為服務層
資料通路在這裡的實作比較簡單,主要是用Linq To Sql來實作IOrderRepository 和IProductRepository接口的,代碼如下所示,此處不再贅述:
public interface IOrderRepository
bool Save(Order order);
public interface IProductRepository
Product GetProductByName(string productName);
最後我們就是處理顯示層。
到這裡Domain Model就基本講述完了,我們可以看出:當軟體中的業務比較的負責的時候,我們用Domain Model可能比較的好。因為用Domain Model的時候,我們的把所有的精力主要關注在對業務領域的模組化,把業務的概念抽象出來,變為軟體可以實作的模型。其實抽象出業務模式不是那麼容易的事情,往往必須對領域作出比較深入的分析才行。
同時,在業務模組化和可實作性之間要有權衡,有時候,我們把業務分析的很透,但是分析出來的概念無法轉為實作,産生了“水至清則無魚”。希望大家多多的琢磨幾種組織業務邏輯模式的差別。
今天就到這裡了,還是希望多多見諒,支援!謝謝啊!
本文轉自yanyangtian51CTO部落格,原文連結:http://blog.51cto.com/yanyangtian/415734 ,如需轉載請自行聯系原作者