一、简介

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

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

二、实战

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

下面通过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模式,组合多种策略,然后施加到用户聚合根上,得到最终的聚合根

转载于:https://www.cnblogs.com/GreenLeaves/p/10201162.html

领域驱动系列五模型驱动设计的构造块相关推荐

  1. 领域驱动设计(DDD)实践之路(四):领域驱动在微服务设计中的应用

    这是"领域驱动设计实践之路"系列的第四篇文章,从单体架构的弊端引入微服务,结合领域驱动的概念介绍了如何做微服务划分.设计领域模型并展示了整体的微服务化的系统架构设计.结合分层架构. ...

  2. 领域驱动系列:三种领域逻辑组织模式的本质

    企业应用架构模式中明确提出了三种领域逻辑组织模式:事务脚本.领域模型和表模块.不少人看的云里雾里的,不少人说的似懂非懂的,主要原因是没有从项目的级别的分析和设计经验,只有单个项目模块的开发经验的人很难 ...

  3. 领域驱动系列-浅析VO、DTO、DO、PO

    一.概念介绍 POJO(plain ordinary java object) :简单java对象,个人感觉POJO是最常见最多变的对象,是一个中间对象,也是我们最常打交道的对象.一个POJO持久化以 ...

  4. 爽,字节架构师DDD(领域驱动设计)巅峰之作,拆解业务代码真好用

    前 言 至少20年前,一些顶尖的软件设计人员就已经认识到领域建模和设计的重要性,但令人惊讶的是,这么长时间以来几乎没有人写出点儿什么,告诉大家应该做哪些工作或如何去做.尽管这些工作还没有被清楚地表述出 ...

  5. 领域驱动设计,让程序员心中有码(三)

    "正如西方古典哲学在现代社会逐渐式微,成为少数内心丰满者们填充自己精神世界的宝贵食物,UML也这样:互联网技术飞速发展的今天,各类软件设计思想层出不穷,正是站在UML和其他各种软件基础理论巨 ...

  6. 领域驱动设计,让程序员心中有码(六)

    领域驱动设计-聚合,一种极简的思维模式 引言 作为IT技术产业飞速发展的产物,软件工程学已经成为当今时代非常重要的一个学科.作为一名资深的软件开发从业者,我们需要学习的东西实际上已经远远超出了原本在大 ...

  7. 初探领域驱动设计(1)为复杂业务而生

    概述 领域驱动设计也就是3D(Domain-Driven Design)已经有了10年的历史,我相信很多人或多或少都听说过这个名词,但是有多少人真正懂得如何去运用它,或者把它运用好呢?于是有人说,DD ...

  8. ddd java repository_初探领域驱动设计(2)Repository在DDD中的应用

    概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...

  9. yang模型中rpc_领域驱动模型(DDD)设计讲解

    一. 什么是领域驱动模型(DDD)? 领域驱动模型一种设计思想,我们又称为DDD设计思想.是一种为了解决传统设计思想带来的维护困难,沟通困难和交互困难而产生的一种新的思想.也解决了在部分公司中,一个项 ...

最新文章

  1. pyside2 安装_PySide2安装踩坑指南
  2. 如何提高android串口kernel log等级
  3. ML之回归预测:以某个数据集为例从0到1深入理解科学预测之回归(实数值年龄预测)问题的思路框架
  4. 干货丨一组图详解元数据、主数据与参考数据
  5. c#和javascript函数的相互调用(ObjectForScripting 的类必须对 COM 可见。请确认该对象是公共的,或考虑向您的类添加 ComVisible 属性。)...
  6. #pragma comment和#pragma 预处理指令详解
  7. qregexp限制数字范围_数字系统实现电压电流控制的必经之路数模转换器
  8. (30)System Verilog进程间同步(邮箱mailbox)
  9. Linux内核分析第一周——计算机是如何工作的
  10. python程序设计实验报告答案大全_Python程序设计实验三
  11. 升降机用三级液压缸的设计与仿真
  12. html5 调速 视频播放器,7款很棒的 HTML5 视频播放器
  13. 织梦首页header实现会员的登录及会员状态显示
  14. 悉尼大学计算机相关专业硕士,悉尼大学计算机硕士课程详细介绍
  15. 计算机一级可以积分入深户吗,怎样积分入深户2019年深户办理条件
  16. CSS3——渐变(线性渐变、径向渐变、重复性渐变)
  17. 中国保险业过去五年基础数据分析
  18. Web移动端Fixed布局的解决方案(原文出处:http://efe.baidu.com/blog/mobile-fixed-layout)
  19. Spring:applicationContext.xml的头文件信息
  20. 小程序快速生成朋友圈海报分享图

热门文章

  1. 一些意想不到的bug
  2. 接口安全怎么处理_压瓦机设备噪声大怎么处理及压瓦机的安全使用
  3. cordova build android很慢,cordova build --release android命令打包下载gradle非常慢的问题...
  4. android左右滑动开关,Android点击左右按钮实现左右滑动页面切换
  5. 码云上传项目时出现空目录的解决办法
  6. 编写linux脚本操作 java 服务
  7. 小程序模拟服务器,小程序模拟请求服务器json数据
  8. PDF 与 Word互转工具。 在线的 和安装软件
  9. C语言调用自定义交换函,C语言函数篇 - personal page of Msingwen - OSCHINA - 中文开源技术交流社区...
  10. linux下如何挂载格式化内存卡,Linux下磁盘挂载格式化