DDD应对运营活动系统腐化实践
前言
任何人类的设计都会腐化,软件系统也不例外
腐化之谜
随着系统的规模增长和复杂度膨胀,系统会慢慢腐化。

于是改一个很简单的下单地址,就会牵动整个交易系统十几处的改动。
如何解决这种腐化之谜呢?
参考计算机系统架构:
一个复杂的计算机系统架构包括:软件系统元素,元素之间的联系,元素本身有自己特有属性。
于是我们可以在架构角度参考计算机系统架构的实现。
架构建模

为达到上面提到的架构建模的目的,引入领域驱动。
领域驱动围绕业务概念构建领域模型,通过分离技术的方式实现应对复杂业务,及系统难以演进问题的解决方案。
DDD带来的不同:
- 将原有以技术角度审视架构演进的视角,转换到以业务视角切入架构。
- 业务复杂度来源于领域本身,深入领域,正确识别出领域深层次概念及关系。
- 将领域知识进行结构性表达,同时与编程模型保持一致,便形成了DDD。
基于问题空间的DDD模式

基于解空间的DDD模式

界限上下文
由显示边界限定的特定内聚职责,领域模型便存在于上下文之内。
界限上下文识别过程:

领域分析
如何通过真实业务驱动需求演化出DDD模型呢?
可以采用事件风暴进行领域分析。
流程:
- PM,运营,RD共聚一堂
- 数小时内理解复杂领域
- 标记简单的UML
- 工作流程与DDD完美匹配
- 事件流演化
以电商系统为例
事件风暴
事件:PM关心真实事件
如:用户订单已发布,商品已发布
说明:关注点在于什么领域模型发生了什么变化。
命令风暴
命令:通过什么活动产生了事件
如:用户提交了订单,开放平台同步商品
说明:命令帮助我们明确系统对外提供的能力,同时明确业务上的输入
命令来源:用户UI界面的操作,外部系统调用触发,定时任务触发
寻找聚合
聚合:一组相关性领域模型的聚合,用来封装业务不变性,确保关联紧密的领域模型内聚在一起
如:订单和商品
聚合的目的在于业务内聚,强迫RD进行简化领域模型的关联,实现业务设计高内聚低耦合的目的
划分界限上下文
- 业务模型的问题是否同一个,是则放在同一个界限上下文中
- 如果一个聚合同时解决了多个问题,则需要定义不同的上下文确定解决特定问题

界限上下文之内可以自由选择架构模式,如MVC,CQRS,微服务,SOA等。
不是所有界限上下文都采用领域驱动方式,非核心子域可参考数据驱动下的面向过程编程。
提取出面向切面的聚合层,以工程技术因素为主要考虑点。
DDD的核心价值在于指导划分界限上下文。

DDD分层设计

领域模型建设思路:
- 业务与技术关注点分离,依赖倒置,内部不依赖于外部且外部可替换
- 接口适配器架构
- 防腐层建设,领域模型依赖稳定性
参考六边形架构:

架构目标:
- 独立于框架
- 与数据库分离
- 可测试性
- 与外部结构分离
- 与UI分离
架构原则:
- 关注点分离,切割不同层
- 依赖原则:外部依赖内部,依赖倒置
- 架构设计围绕用例
结合CQRS设计
CQRS:命令查询职责分离
将更复杂的领域模型拆分为读取和写入两部分。
将消息传递,数据日志同步,领域事件和事件溯源使用到特定上下文。

领域驱动实践
目前我们活动营销系统中,存在大量迭代需求都是针对运营需求所设计,需求本身具有复杂性和持续迭代性,故均已转换采用领域驱动设计方式实现。
对现有及可预期的玩法需求进行了逻辑抽象,提供了统一业务领域玩法模型,为运营提供统一玩法配置管理平台,进行玩法需求配置,经过领域系统内核进行集成,对用户输出统一玩法活动UI及流程。
在局部演进及扩展需求,采用元数据+大字段应对信息的不确定性,流程引擎+规则引擎构造玩法,DSL提供动态创建玩法资源配置的能力。
梳理事件风暴,抽象命令风暴,寻找履行命令的业务名词,对类似的名词玩法进行共性提取,做合适的抽象,同时建立通用语言描述及定义。
采用DDD分层架构+六边形架构+CQRS模型,使得系统具备面向领域驱动的演进能力。
最后
DDD不是银弹
哪些产品适用于DDD:
- 是否是复杂问题,或者子域内具有复杂性
- 业务是否重要且有很高的预期
- 是否可以让运营和PM介入
- 遵循迭代式的开放方法
领域模型好坏的标准:
- 模型反映了对于问题的抽象,抽象没有统一的标准
- 模型是迭代演进的,需要持续集成,改进
- 通用语言,领域模型和代码目标意图一致
更多交流:

DDD应对运营活动系统腐化实践的更多相关文章
- No zuo no die:DDD 应对具体业务场景,Domain Model 重新设计
写在前面 上联:no zuo no die why you try 下联:no try no high give me five 横批: let it go上联:no zuo no die why y ...
- DDD 应对具体业务场景,Domain Model 重新设计
DDD 应对具体业务场景,Domain Model 重新设计 写在前面 上联:no zuo no die why you try 下联:no try no high give me five 横批: ...
- 升讯威微信营销系统开发实践:(1)功能概要与架构设计( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
- Zabbix监控系统深度实践
Zabbix监控系统深度实践(企业级分布式系统自动化运维必选利器,大规模Zabbix集群实战经验技巧总结,由浅入深全面讲解配置.设计.案例和内部原理) 姚仁捷 著 ISBN 978-7-121-24 ...
- 升讯威微信营销系统开发实践:订阅号和服务号深入分析( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
- 京东基于Spark的风控系统架构实践和技术细节
京东基于Spark的风控系统架构实践和技术细节 时间 2016-06-02 09:36:32 炼数成金 原文 http://www.dataguru.cn/article-9419-1.html ...
- 从游击队到正规军(三):基于Go的马蜂窝旅游网分布式IM系统技术实践
本文由马蜂窝技术团队电商交易基础平台研发工程师"Anti Walker"原创分享. 一.引言 即时通讯(IM)功能对于电商平台来说非常重要,特别是旅游电商. 从商品复杂性来看,一个 ...
- 大型网站系统架构实践(五)深入探讨web应用高可用方案
从上篇文章到这篇文章,中间用了一段时间准备,主要是想把东西讲透,同时希望大家给与一些批评和建议,这样我才能有所进步,也希望喜欢我文章的朋友,给个赞,这样我才能更有激情,呵呵. 由于本篇要写的内容有点多 ...
- 升讯威微信营销系统开发实践:(4)源代码结构说明 与 安装部署说明( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
随机推荐
- Linux(常用)命令
目录 Linux(常用)命令 系统信息 关机 (系统的关机.重启以及登出 ) 文件和目录 文件搜索 挂载一个文件系统 磁盘空间 用户和群组 文件的权限 - 使用 "+" 设置权限, ...
- Fortify漏洞之Portability Flaw: Locale Dependent Comparison
继续对Fortify的漏洞进行总结,本篇主要针对 Portability Flaw: Locale Dependent Comparison 漏洞进行总结,如下: 1.Portability Flaw ...
- Protobuf的上手使用
这里不赘述Json和Protobuf的比较和区别,只谈谈简单的使用 1.在Client-Server交互的过程中,都是以二进制数据传输,所以Json和Protobuf在使用的过程中,都存在序列化和反序 ...
- laravel——表操作集成操作
背景:通过判断不同的请求参数,返回不同的需要的数据 一.准备工作: 数据库新建一个表 DROP TABLE IF EXISTS `tb_category2`; CREATE TABLE IF NOT ...
- 一个关于integer表示范围的问题
1:在做字符串parse为integer 类型市,一直出现问题就是当我parse “”2851663837”报错, 但是当我parse “1417585794” 可以.原来是超出integer 类型 ...
- Python——字符串增加颜色
给显示字符添加颜色: salary=int(input('\033[31;1m请输入你的工资:\033[0m')) ('\033[;1m请输入你的工资:\033[0m') 3x是给字符串改变颜色 31 ...
- amazeui datepicker日历控件 设置默认当日
amazeui datepicker日历控件 设置默认当日 背景: 最近在做一个系统的时候,前台需要选择日期,传给后台进行处理,每次都需要通过手动点击组件,选择日期,这样子很不好,所以我想通过程序自动 ...
- 2013.4.19 - KDD第一天
其实昨天KDD就开始了,不过今天算是我跟KDD的第一天. 昨天夜里就短信跟中秋聊了一会儿,然后中秋说他一天都在弄数据库,连不上怒了.然后我跟他说明天我来.于是今天就在图书馆弄KDD,数据是用数据库 ...
- linux 下安装node 并使用nginx做域名绑定
#1 ,home目录下 下载nodejs安装包,解压 并修改文件夹名称 wget https://nodejs.org/dist/v8.11.4/node-v8.11.4-linux-x64.tar. ...
- java容器三:HashMap源码解析
前言:Map接口 map是一个存储键值对的集合,实现了Map接口的主要类有以下几种 TreeMap:用红黑树实现 HashMap:数组和链表实现 HashTable:与HashMap类似,但是线程安全 ...