這篇文章其實是大健康行業直銷系統的番外篇,主要給大家講講如何在領域邏輯中,有效的處理業務邏輯條件判斷的最佳實踐問題。
大家都知道,聚合根、實體和值對象這些領域對象都自身處理自己的業務邏輯。在業務處理過程中,通常會有一些條件判斷,當滿足這些條件時,會進行不同的后續處理。在傳統的實現中,可以通過If Else條件語句進行判斷,但If Else語句在復雜領域中來檢查是否滿足一些業務條件存在以下的問題:
1. 無法很好的顯示表達業務條件本身。
2. 無法對多個條件在不同需要的地方進行靈活的組合。
為了更好的組織業務邏輯中關於業務條件的判斷,最佳實踐方式是將業務條件拆分得足夠細,並用語義化的方式表示。這樣,在當前上下文中的領域對象就可以使用一個或多個業務條件的組合。
舉個例子:酒店業務中,房間領域對象會處理預定房間的領域邏輯和退房的領域邏輯,在預定房間時,我們需要保證房間沒有被其他人預定並且房間沒有正在維護這兩個業務條件同時滿足;在退房時,我們需要保證房間里沒有物品損壞或已經進行了損壞賠償這兩個業務條件中的任意一個。
要實現上述的需求,我們可以分別作出4個業務條件規則,然后在界限上下文任意要使用的地方進行靈活的組合。
1. 為了達到上述目的,我們首先要開發出業務條件的接口與條件的組合方式定義。
public interface ISpecification<T> { bool IsSatisfied(T entity); }
該規約接口就定義了一個方法,傳入某個領域對象,判斷是否滿足條件。
public class AndSpecification<T> : ISpecification<T> { private ISpecification<T> left; private ISpecification<T> right; public AndSpecification(ISpecification<T> left,ISpecification<T> right) { this.left = left; this.right = right; } public bool IsSatisfied(T entity) { return this.left.IsSatisfied(entity) && this.right.IsSatisfied(entity); } }
該類實現了兩個業務條件的與關系。
public class OrSpecification<T> : ISpecification<T> { private ISpecification<T> left; private ISpecification<T> right; public OrSpecification(ISpecification<T> left, ISpecification<T> right) { this.left = left; this.right = right; } public bool IsSatisfied(T entity) { return this.left.IsSatisfied(entity) || this.right.IsSatisfied(entity); } }
該類實現了兩個業務條件的或關系。
2. 在房間業務界限上下文中,分別實現4個業務條件規則。
//房間沒有被其他人預定業務條件判斷 public class RoomIsNotConfirmedByOtherSpecification : ISpecification<Room> { public bool IsSatisfied(Room entity) { return !entity.OtherConfirmed; } } //房間沒有被正在維護業務條件判斷 public class RoomIsNotMaintenanceSpecification : ISpecification<Room> { public bool IsSatisfied(Room entity) { return !entity.Maintenancing; } } //房間沒有物品損壞條件判斷 public class RoomIsNotAnythingBrokenSpecification : ISpecification<Room> { public bool IsSatisfied(Room entity) { return !entity.AnythingBroken; } } //房間沒有物品損壞條件判斷 public class RoomHasBeenBrokenCompensateSpecification : ISpecification<Room> { public bool IsSatisfied(Room entity) { return entity.HasBeenCompensated; } }
3. 在房間領域對象的預定房間與退房的領域邏輯中,組合使用上述4個條件規則
//預定房間 public Room Reservation() { var roomisnotconfirmedspec = new RoomIsNotConfirmedByOtherSpecification(); var roomisnotmaintenancespec = new RoomIsNotMaintenanceSpecification(); var researvationrulespec = new AndSpecification<Room>(roomisnotconfirmedspec, roomisnotconfirmedspec); if (researvationrulespec) { //進行后續業務處理 } return this; } //退房 public Room CheckOut() { var roomisnotanythingbrokenspec = new RoomIsNotAnythingBrokenSpecification(); var roomhasbeenbrokenspec = new RoomHasBeenBrokenCompensateSpecification(); var checkrulespec = new OrSpecification<Room>(roomisnotanythingbrokenspec, roomhasbeenbrokenspec); if (checkrulespec) { //進行后續業務處理 } return this; }
當然如果要任意組合多個與、或業務條件,需要在規約上實現Or、And方法來形成鏈式調用,具體怎么實現?有了上面的思路,自己寫代碼試試吧。
QQ討論群:309287205
DDD實戰進階視頻請關注微信公眾號: