前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >领域驱动系列五模型驱动设计的构造块

领域驱动系列五模型驱动设计的构造块

作者头像
郑小超.
发布2019-01-03 15:10:31
8890
发布2019-01-03 15:10:31
举报
文章被收录于专栏:GreenLeavesGreenLeaves

一、简介

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

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

二、实战

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

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

项目结构如下:

代码如下:

代码语言:javascript
复制
    /// <summary>
    /// 用户聚合根
    /// </summary>
    public class UserAggregate
    {
        /// <summary>
        /// 抽象的用户
        /// </summary>
        public AbstractUser AbstractUser { get; set; }
    }
代码语言:javascript
复制
    /// <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; }
    }
代码语言:javascript
复制
    /// <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;
        }
    }
代码语言:javascript
复制
    /// <summary>
    /// 普通用户
    /// </summary>
    public class NormalUser : AbstractUser
    {
        public  override string UserName { get; set; }

        public override int Age { get; set; }

        public override double OrderPrice { get; set; }
    }
代码语言:javascript
复制
    /// <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; }
    }
代码语言:javascript
复制
    /// <summary>
    /// 用户计价聚合根约束
    /// </summary>
    public interface IUserPriceAggregateFactory
    {
        UserAggregate CalculatePrice(IUserPriceAggregateStartegies startegies);
    }
代码语言:javascript
复制
    /// <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;
        }
     
    }

控制台调用代码如下:

代码语言:javascript
复制
    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模式,组合多种策略,然后施加到用户聚合根上,得到最终的聚合根

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-12-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档