谈DDD前,咱们先思考一个问题,什么是好的代码?面试
易于维护,逻辑清晰,健壮,可扩展性强…对于这个问题每一个人都有本身的答案,但至少有一点好的代码必定是易读的。不妨在写每一个函数前想一想若是交付测试,可否作到见名思意,若是存在过多的沟通成本或多或少是存在一些问题的。回到设计上也同样,好的设计也应当便于理解,能让人抓的注重点。编程
DDD想必你们也都听过,domain-driven design领域驱动设计,也是最近几年炒得火热的名词,相关的博客和书籍也有不少(推荐阅读下《领域驱动设计》)。这里不过多扫盲DDD是什么,但从与小伙的交流来看,仅仅经过书本仍是很难理解DDD的精髓的(初学者刚开始看不懂《领域驱动设计》是很正常的,不要着急)。这里我谈下我对DDD的理解,但愿对对你们有所裨益。设计模式
咱们须要认识一点DDD不一样于23种设计模式有标准的实现,换句话说DDD不是以工具化(框架)的方式直接应用于咱们项目中的(不要抱着过于功利化的心态去学习DDD),DDD更多的是一种编程思想或者说是对OOP落地的工程化指导。OOP所倡导的高内聚低耦合,也是咱们使用DDD所要达到的最终目标(微服务的改造也是要作到服务的高内聚低耦合,这也是为何领域可以最终以微服务的形式存在的缘由,由于他们本质上解决的是共同问题)。安全
大部分人都学过OOP,一样不少人并不知道OOP该如何在咱们的实际项目中落地。题外话,我以为这个问题和咱们的高等教育和如今行业发展示状是有关的,没有维护糟糕的系统的经验想让一个初学者理解理解面向对象的意义不现实,而且在工做要求上这一块也是被轻视的(我想毕业后的面试应该不多有人会被问到面向对象了吧,更多的会被问到对框架原理的理解使用),愈加成熟的技术框架的应用也从某种程度上掩盖了技术人员在这方面的缺失。这里的改变,第一点我想说的是思想的转变,对面向对象(或DDD)的理解的重要程度应当不啻于咱们对于高级语言底层知识的重视度,高级语言底层知识的掌握是技术技巧的基础,而面向对象是工程化技巧的基础。框架
再回到项目开发落地上,使用DDD咱们须要做出什么样的变化。首先咱们谈谈不用DDD的开发过程,通常而言咱们都绕不开MVC(我指的MVC不只限于MVC框架,SOA中的对外API从某种程度上说也是VIEW的一种体现),在这个思想的指导下咱们通常的开发过程是对外设计API、对内设计存储层(DB)以及系统间交互流程。这个过程当中咱们每每聚焦的是对外的API实体及存储的实体设计,而API实体、存储层实体他们自己解决的是数据传输的问题,没法去承载过多的业务意义(试想一下你的业务逻辑被写到了API实体内运行在其余人的服务进程中,这岂不是反服务化?而存储层的实体中加入过多的逻辑,很容易致使存储层的逻辑稳定性出现问题)。在这个前提下,作的好,咱们能守住MV(model&view)对外来隐藏好内在逻辑,但对内却将复杂易变的C(control)至于混沌之地(每每咱们会采用过程化的方式去实现,将”数据”的生命周期的管理分散到了不一样的函数中)。使用DDD最重要的就是改变咱们原有的过程化的数据为驱动的编程模式,而是以实体为核、事件驱动来响应数据变化(谈到这里,想必会有人质疑,以为“虚”)。那么先谈谈DOMAIN-DRIVEN的好处?dom
传统的数据驱动的编程模式的缺陷是什么?上面也谈到了,“数据生命周期”的控制是被分散在不一样的函数中,而一旦产生了这种分散是很难再作到高内聚的,想必你们也常常遇到数据在某些不该该被修改的状态下却产生了变化。因此在使用DDD的过程当中咱们首先聚焦的是领域实体的创建,并尝试经过领域实体去解释上面谈到的“数据生命周期”(怎么创建领域实体能够参考《领域驱动设计》中第五章的介绍,在结合项目去体会一下)。数据是没有生命周期的,但实体是有的(这也是如何识别实体和值的最关键区别),在这个前提下,咱们彻底可以控制让实体在什么样的状态响应什么样的事件(安全性、惟一性)。函数
另外咱们经过实体来驱动业务的过程,实际上实体也是对应用层逻辑与存储层的隔离,而且这个过程当中咱们创建的是充血模型,这就给避免后续业务的变化去过多的影响存储设计或者应用层设计,能将变化约束在模型中。给实体赋能带来的另一个好处是让单元测试变得更容易落地,由于这个过程当中隔离了外部数据依赖、存储依赖,避免过长的数据链条,方便将咱们的测试重点聚焦于对实体的职能(这也是咱们核心逻辑所在)。微服务
说到这里,DDD应该是咱们落地微服务、MVC的一个补充,从实践经验来讲,咱们不妨先忘掉接口、忘掉DB结构设计,先去尝试创建模型,去想一想每一个需求对应到这个模型的什么职能(这个过程甚至只须要是一些伪代码或者功能草稿)。创建完模型,再经过系统间的交互流程去验证模型是否正确,进而向上去设计接口、向下去设计存储结构。工具
未完待续...单元测试