zoukankan      html  css  js  c++  java
  • 领域驱动系列五模型驱动设计的构造块

    一、简介

    为了保证软件实现的简洁性,并且与模型保持一致,不管实际情况有多复杂,必须使用建模和设计的最佳实践,即让通过我们的编程技术(设计模型、指责驱动、契约式设计)充分地体现领域模型,并保持模型地健壮性和可扩展性,而不是单单地实现模型.某些决策设计能和模型紧紧地结合,这种结合要求我们注意每个元素地细节.

    开发一个好的领域模型是一门艺术,而模型中的各个元素的实际设计和实现则相对系统化,将领域设计(也可以是软件系统中的其他关注点)与软件系统中的其他关注点(也可以是领域设计)分离使整个领域模型非常的清晰.根据不同模型的指责(特性)会使元素的意义更加鲜明.

    二、实战

     上图展示的模型驱动设计的基本构造块,当然实际开发中可能不止这些内容,可能还会有施加在实体上的一些契约还有一些特殊的计算规则、可能还有有一些复杂的实体运算,这些运算可能还需要使用一些设计模式去设计等等.但这个基本的构造.

    下面通过C#代码来实现一个简单的用户订单计价系统,如下:

    项目结构如下:

    代码如下:

        /// <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;
            }
         
        }

    控制台调用代码如下:

        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();
            }
        }

    根据上面的代码可以得出一个基本的领域模型,如下:

     

    注意下图

     

    这个过程可以随意组合,可以通过Facade模式,组合多种策略,然后施加到用户聚合根上,得到最终的聚合根

  • 相关阅读:
    MongoDB入门示例及介绍
    Oracle/PLSQL CURSOR FOR Loop
    JAVA写的文件分割与文件合并程序
    synchronized 解决死锁的问题 轉貼
    采用批处理命令对文件进行解压及采用SQLCMD进行数据库挂载
    chapter6作业
    chapter5作业
    chapter4作业
    Linuz系统管理 -----账号管理
    chapter02
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/10201162.html
Copyright © 2011-2022 走看看