领域模型为解决软件的复杂性而生。架构
人月神话说:软件的复杂性是软件的本质属性之一。框架
2004年,Eric Evans写就了《领域驱动设计——软件核心复杂性应对之道》(注意书的副标题)oop
若是你的软件项目有如上问题,那么是时候考虑DDD了,若是没,不要XJB上DDD。(不要瞎引入复杂性,DDD自己比较耗费脑子)。好比写个代码几年不增长需求,别想太多,撸完就算了。测试
怎么解决复杂性问题?9年制义务数学教育告诉咱们,不外两种方法:抽象、分治。spa
抽象:任何一个业务问题,均可以最终简化为一个或者几个基本原理的问题,这些个基本原理问题,就叫作领域问题。线程
领域问题是某一类问题的高度抽象。它关注的不是某一笔业务,某一个请求,而是全部相似的,具备同类属性的问题,是一个通用的解决方案。设计
是一个化繁为简的东西。他是真正简化问题的关键。对象
领域模型能不能简化问题,关键要看这个。开发
分治:任何一个业务问题,经常是几个领域的综合。如何去肯定,区分到底划分为几个领域模型部署
(依据是什么呢?其实就是内聚和耦合)
在DDD中,形式上,它讲了一大堆层次模型和六边形模型。这些既不重要,也很重要。
不重要的是,他对于你对具体某个业务领域的抽象和分治毫无做用——这只能依赖于你对业务的理解,依赖你的思考方式和抽象——而这,才是DDD的核心。
重要的是,他从代码形式上抽象了几乎全部代码都一定符合的结构——而且研究了代码如何写才更科学——这对写出漂亮的代码颇有帮助
举例LInux管道命令为啥如何灵活,如此强大
这是由于
1,抽象全部东西都是文件
2,全部文件都有输入 ,输出,错误输出,若是没定义,走标准输出入
3,管道是一个定义两个文件的之间的文件,做用是前者的的stdout做为后者的stdin
Netty也很强大,可是也很简单核心概念只有三个EventLoop,Channel,Handler
EventLoop定义了如何去调度线程和Io的方法
Channel定义了各类IO类型,能够实现各类状况下Nio,Upd……等Io协议
Handler是业务(线程)的抽象
能够看到,这里强大的根源和精髓的地方实际上是LINUX的概念抽象,和概念之间的机制做用。而和用什么语言,用什么框架,3层模型仍是六边形模型,代码写的好很差……等因素毫无关系
抽象是DDD的精髓。六边形,层次模型对代码实现比较有意义
用好DDD的关键是
1,深入了解业务领域知识,了解业务概念,
2,根据业务模型,合理抽象建模(高度简化问题)
3,(操做实现层面)尽可能少的引入复杂性(尽可能少引入技术框架,用最简单的方式去解决问题)
不要在讨论业务的时候就考虑技术实现
因此这里强调一下咱们的架构原则
1,业务和技术分离
2,技术和部署分离
3,变与不变分离
QA和回答纪要
1,老徐:DDD解决复杂性
2,翠翠:DDD关键是抽象
3,冯昌:TDD和DDD(跑题了)
TDD是测试驱动开发,要解决的问题和DDD(复杂性)没有关系。共通点是两个DD。
TDD的合理性和正确性成疑,不必定是一个好的方法。这个问题后续单独讨论。
4,徐康:DDD是一种最佳实践。
好比业界如今都怎么搞,你们都这么搞。
A:DDD是一种理念,而不是一种实践。理念是完美的,实践不必定是(举了某project2的例子)。
而且实践是时时刻刻在变化的,某一时完美,不表明下一时完美。要作到完美,开发人员必须有评价完美的标准——DDD,抄袭和采纳——那不可能铸就完美,由于咱们本身的业务永远有特性。
5,刀刀:DDD和充血模型
Q:充血模型是对的,比较好的代码都会采用这种方式,他解决了什么问题?什么代码和逻辑应该放到充血模型中?
A:充血模型是对代码微观结构复杂度的治理。
系统划分、模块划分、对象设计、领域模型、充血模型……全部这些有一个想通之处:封装——耦合和内聚。
咱们既然强调SOA是一种宏观结构的良好治理,DDD是一种概念领域结构的良好治理,那么就必然认为充血模型之一种代码微观结构的良好治理
那么哪些逻辑应该放到充血模型中?
1,本身的的数据的逻辑
2,两个模型之间的逻辑
这种逻辑两个模型中均可以放,看谁是少方。
好比人吃肉。通常eat放人里合适。可是若是业务是人吃肉,狗吃肉,猪吃肉……那么eat逻辑放肉里比较 好。
6,京其:领域划分的依据
内聚和耦合(本质是效率和复杂度)
以订单支付系统为例,什么状况下能够是同一个系统,什么状况下不能够。
创业的时候,不少创业公司订单和支付单是同一个。
公司业务更丰富,更多,他们就必须分开了。
分开的依据是耦合和内聚。