走向.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);
}
最後我們就是處理顯示層。
在本例子中,顯示層就是用傳統的ASP.NET來實現的,而且用了最簡單的實現,如果需要,大家可以採用MVP模式,這點在我的另一文章(走向.NET架構設計—第三章—分層設計,初涉架構(中篇) )中詳細的講述了,這裡不在贅述,也希望大家見諒。
到這裡Domain Model就基本講述完了,我們可以看出:當軟體中的業務比較的負責的時候,我們用Domain Model可能比較的好。因為用Domain Model的時候,我們的把所有的精力主要關注在對業務領域的建模,把業務的概念抽象出來,變為軟體可以實現的模型。其實抽象出業務模式不是那麼容易的事情,往往必須對領域作出比較深入的分析才行。
同時,在業務建模和可實現性之間要有權衡,有時候,我們把業務分析的很透,但是分析出來的概念無法轉為實現,產生了“水至清則無魚”。希望大家多多的琢磨幾種組織商務邏輯模式的區別。
今天就到這裡了,還是希望多多見諒,支援!謝謝啊!