領域驅動系列五模型驅動設計的構造塊

1、簡介數據庫

爲了保證軟件實現的簡潔性,而且與模型保持一致,無論實際狀況有多複雜,必須使用建模和設計的最佳實踐,即讓經過咱們的編程技術(設計模型、指責驅動、契約式設計)充分地體現領域模型,並保持模型地健壯性和可擴展性,而不是單單地實現模型.某些決策設計能和模型牢牢地結合,這種結合要求咱們注意每一個元素地細節.編程

開發一個好的領域模型是一門藝術,而模型中的各個元素的實際設計和實現則相對系統化,將領域設計(也能夠是軟件系統中的其餘關注點)與軟件系統中的其餘關注點(也能夠是領域設計)分離使整個領域模型很是的清晰.根據不一樣模型的指責(特性)會使元素的意義更加鮮明.設計模式

 

2、實戰微信

 上圖展現的模型驅動設計的基本構造塊,固然實際開發中可能不止這些內容,可能還會有施加在實體上的一些契約還有一些特殊的計算規則、可能還有有一些複雜的實體運算,這些運算可能還須要使用一些設計模式去設計等等.但這個基本的構造.ide

 

下面經過C#代碼來實現一個簡單的用戶訂單計價系統,以下:spa

項目結構以下:設計

代碼以下:3d

    /// <summary>
    /// 用戶聚合根
    /// </summary>
    public class UserAggregate
    {
        /// <summary>
        /// 抽象的用戶
        /// </summary>
        public AbstractUser AbstractUser { get; set; }
    }
    /// <summary>
    /// 抽象的用戶,裏面定義用戶的基本屬性
    /// </summary>
    public abstract class AbstractUser
    {
        /// <summary>
        /// 值對象
        /// </summary>
        public abstract string UserName { get; set; }

        /// <summary>
        /// 值對象
        /// </summary>
        public abstract int Age { get; set; }

        /// <summary>
        /// 值對象 訂單價格
        /// </summary>
        public abstract double OrderPrice { get; set; }
    }
    /// <summary>
    /// 計價策略類,具體的計算規則,隨着業務的變化,可已從新實現
    /// </summary>
    public class UserPriceAggregateStartegy : IUserPriceAggregateStartegies
    {
        public double CalculatePrice(UserAggregate user)
        {
            double totalfee = 0;
            if (user.AbstractUser is WxUser)
            {
                //這裏具體的優惠尺度能夠去讀取配置文件
                totalfee=user.AbstractUser.OrderPrice * 0.8;
            }
            else if (user.AbstractUser is NormalUser)
            {
                totalfee=user.AbstractUser.OrderPrice;
            }
            return totalfee;
        }
    }
    /// <summary>
    /// 普通用戶
    /// </summary>
    public class NormalUser : AbstractUser
    {
        public  override string UserName { get; set; }

        public override int Age { get; set; }

        public override double OrderPrice { get; set; }
    }
    /// <summary>
    /// 微信用戶
    /// </summary>
    public class WxUser: AbstractUser
    {
        public override string UserName { get; set; }

        public override int Age { get; set; }

        /// <summary>
        /// 微信用戶的OpenId
        /// </summary>
        public string OpenId { get; set; }

        /// <summary>
        /// 值對象 訂單價格
        /// </summary>
        public override double OrderPrice { get; set; }
    }
    /// <summary>
    /// 用戶計價聚合根約束
    /// </summary>
    public interface IUserPriceAggregateFactory
    {
        UserAggregate CalculatePrice(IUserPriceAggregateStartegies startegies);
    }
    /// <summary>
    /// 用戶聚合根工廠,按照計價策略生成對應的用戶實體,這個類會暴露給外面的業務結構使用
    /// 將業務邏輯的處理交給工廠類,這樣作的好處,是減輕控制器的壓力,也符合領域驅動設計的理念
    /// </summary>
    public class UserPriceAggregateFactory: IUserPriceAggregateFactory
    {
        private UserPriceAggregateFactory() { }

        private UserAggregate _userAggregate;

        public UserPriceAggregateFactory(UserAggregate userAggregate)
        {
            _userAggregate = userAggregate;

        }

        public UserAggregate CalculatePrice(IUserPriceAggregateStartegies startegies)
        {
            var price=startegies.CalculatePrice(_userAggregate);
            _userAggregate.AbstractUser.OrderPrice = price;
            return _userAggregate;
        }
     
    }

控制檯調用代碼以下:code

    class Program
    {
        static void Main(string[] args)
        {
            //拿到用戶的輸入
            var normalUser = new WxUser()
            {
                UserName = "小超",
                Age = 23,
                OrderPrice = 6
            };

            //組成業務聚合根
            var aggregare = new UserAggregate()
            {
                AbstractUser = normalUser
            };

            //生成用戶計價類型的聚合根
            var user = new UserPriceAggregateFactory(aggregare);

            //生成具體的計價類型
            var startegy = new UserPriceAggregateStartegy();

            //生成計價事後的業務聚合根
            var priceUser = user.CalculatePrice(startegy);

            //隨後將通過業務計算後的聚合根經過倉儲初始化到數據庫中
            //.....省略

            Console.WriteLine("當前用戶的訂單價格爲:{0}", priceUser.AbstractUser.OrderPrice);
            Console.ReadKey();
        }
    }

根據上面的代碼能夠得出一個基本的領域模型,以下:orm

 

注意下圖

 

這個過程能夠隨意組合,能夠經過Facade模式,組合多種策略,而後施加到用戶聚合根上,獲得最終的聚合根

相關文章
相關標籤/搜索