Coder Social home page Coder Social logo

ddd-demo's Introduction

本项目是为了适配掘金小册:《深入浅出DDD》讲解的演示项目。

为了能够更好的理解Demo中的分层与逻辑处理,我强烈建议你配合小册来深入了解DDD。

你可以通过以下方式联系我,进入DDD讨论群

  • 微信号:baiyan_lou
  • 微信公众号:柏炎大叔
  • 掘金

欢迎大家给Demo提出Issue

如果你觉得项目还不错,给个Star吧~

一、为什么我们要使用DDD

我相信基本上 99% 的 Java 开发读者,不管你是计科专业还是跨专业出身,初学 Spring 或 SpringBoot 进行 Web 开发的时候,接触到的代码分层都是 MVC 架构。

MVC,全称 Model View Control(模型-视图-控制器),其分层定义如下。

  • M(模型层/DAO层) :业务数据载体层。

  • V(视图层/Controller层) :展现给用户的数据表示层。

  • C(控制层/Service层) :接受 V(视图层)传递过来的请求进行业务逻辑处理,并将处理后的 M 层(模型层)数据返回给 V(视图层)。

因为 MVC 对于刚刚接触 Web 开发的同学来说有它自身独有的优势:

  • 分层简单易懂;

  • 层级逻辑替换方便;

  • 可以降低层与层之间的依赖;

  • 有利于标准化;

  • 利于层与层逻辑的复用。

但真实情况是这样吗?随着系统功能迭代,业务功能越来越丰富之后,控制层里面对于业务逻辑处理的代码也越来越多,维护成本也越来越高

举个例子:你负责了一个 MVC 项目从 0 到 1 的搭建,后面业务越来越好,招了新的研发一起迭代需求。在版本迭代的过程中,Service 层逻辑方法类似又不完全相同。A 同学拷贝了你的代码,改了一小段逻辑,开了一个新的方法。B 同学看到两个类似的逻辑,偷偷在里面加了一个 if/else 的判断。C 同学再按照自己的理解去写了一个已经存在的逻辑……

那么,随着时间的推移,你会遇到什么样的工程问题呢?

  • 工程体积庞大;

  • 需求迭代会出现明明是类似的功能,却无法复用代码逻辑的情况;

  • 重复的代码很多;

  • 大类(几千上万行)随处可见;

  • 出了 Bug 不敢直接修复,只能继续往上贴逻辑;

  • 代码可读性很差,不加注释你都难以理解业务逻辑;

  • 功能之间耦合严重,改了一个 Bug,莫名其妙又出现了好几个其他的 Bug;

  • 外部系统 RPC 接口修改,大范围影响到本系统的逻辑;

  • ……

归根到底的原因是什么?

控制层就像个万能容器,什么代码都往里面写,承载了它这个年纪不该承受的业务逻辑。反观模型层与视图层,空空如也。业务逻辑不是跟着业务模型走的,而是在现有数据模型的情况下,或者先设计数据模型的情况下去迭代了业务需求。业务模块之间的边界被淡化,控制层内逻辑只要能实现需求,想怎么写就怎么写,没有一个规范与规约。

为了解决常规中大型 Web 系统 MVC 架构下存在的弊端问题,这就引出了 DDD。这也是本小册的大主题。在本小册中,我会带你看 DDD 如何从业务模型与业务边界出发去设计代码层级结构,将散落的、重复的逻辑内聚到业务模型中。从基础概念出发到落地实战演示,带你进入 DDD 的世界。

今天这一讲的内容相较而言偏原理些,都是讲解 DDD 相关的基础信息。虽然基础,但很关键,毕竟只有夯实好基础,而后才能更好地实战。

二、DDD如何解决MVC痛点

业务的交互方式要分为两种:系统内部交互,系统与外部交互。

MVC 分层下,不论是系统内交互还是系统与外部交互,逻辑都是按照功能点被杂糅在一起。Service 层利用 DO、DTO、VO 等业务 POJO 作为数据载体,完成了所有模型之间的逻辑处理、数据转换等跟业务有关或者无关的事情。Service 层臃肿且条理不清晰。就像是吃大乱炖,什么都往里面加,反正最后能吃就行。而这些 POJO 除了字段属性,内部没有任何的业务逻辑,这就是典型的贫血模型

DDD 核心**是什么呢?解耦与内聚!建立领域模型形成聚合根,将原先散落在 Service 层的业务逻辑收拢到领域模型内部,变成充血模型,聚合即为业务。业务不是像炒大锅饭一样混在一起,而是一道道工序复杂的美食,都有它们自己独立的做法。

下面来看看 DDD 是如何处理这两种交互方式的。

1.系统内部交互

DDD 的价值观里面,任何业务都是某个业务领域模型的职责体现。为了完成某一个需求功能,将核心的业务逻辑定义在领域内部,应用服务层编排调用领域中的业务方法来实现功能点的需求。也就是说,业务功能是领域所供的能力的组合。

这样,每个领域只会做自己业务边界内的事情,最小细粒度地去定义需求的实现。原先模型层空空的贫血模型摇身一变,变成了充血模型。进到应用服务层,你的代码就是你的业务逻辑。逻辑清晰,可维护性高!

2.系统与外部交互

假如微服务体系下,有一个下订单的需求。在通过订单服务下订单前,需要先请求用户服务获取下单用户的个人信息,如下图,用户服务在版本 A 时获取用户详情的接口是 interfaceA,版本 B 时换成 interfaceB。那么就会出现,需要修改订单服务中获取用户信息的逻辑。如果类似的逻辑散落在系统的很多地方,就会出现外部系统的业务逻辑变更,造成了本系统的大量依赖变更。

从上面的例子可知,系统内部完成业务逻辑可能会与外部系统进行交互,而此时外部系统一旦发生逻辑变更,将会影响到任意一个系统内依赖外部系统的逻辑。

为了解决这个痛点问题,DDD 通过定义适配器包装对外部系统的依赖。系统内部直接依赖适配器,由适配器去调用外部接口,减小外部系统的变动对本系统业务逻辑的影响。

三、DDD的优势是什么

通过上面的介绍和剖析,不难总结出 DDD 主要有以下优势。

  • 从业务出发,自顶向下设计系统,优先考虑领域模型,而不是切割数据和行为,告别贫血模型;
  • 领域设计简化复杂业务,内聚逻辑实现,准确传达业务规则,分而治之;
  • 应用服务层的编排即展示了业务逻辑,增强了代码的可读性与可维护性;
  • 消除业务参与人员的信息不对称,提升协助效率;
  • 将外部系统等不可控因素转化为可控因素,减小系统间依赖;
  • 适合于业务复杂的中台化的系统设计。

四、到底什么样的系统适配DDD

看完上文对于 DDD 的分析之后,你是不是觉得一对比,MVC 简直就是“弟弟”?但是你回过头来想想,DDD 其实在十几年前就已经被提出来了,但为什么是近几年才开始逐渐进入大众的视野呢?总结起来,主要有以下几条原因。

  • DDD 的结构不像 MVC 结构那么简单,分层更加复杂。

  • 消除信息不对称的成本比较大,需要多方人员协作讨论业务模型。

  • 迭代快的小系统不如直接使用 MVC 做好代码规范能够更快地上线。

因此,不适配 DDD 的系统是什么呢?

  • 中小规模的系统,本身业务体量小,功能单一,选择 MVC 架构无疑是最好的。

  • 项目化交付的系统,研发周期短,一天到晚按照甲方的需求定制功能(这种本身业务需求边界就不清晰,功能的可持续迭代性就很差,而且这种系统一般就是一口价买卖),这种也最好选择 MVC。

那相反地,适配 DDD 的系统是什么呢?中大规模系统,产品化模式,业务可持续迭代,可预见的业务逻辑复杂性的系统。

总而言之就是:

  • 你还不了解 DDD 或者你们系统功能简单,就选择 MVC;
  • 你不知道选用什么技术架构做开发,处于业务探索阶段,选用 MVC;
  • 其他时候就酌情考虑 DDD。

五、分支说明

Demo代码包含了灰度分层架构 (分支:v0.0.2-SNAPSHOT) 与能力分层架构 (分支:mater)

两种分层架构的特点与优势已经在小册章节《DDD的分层详解》中详细叙述。由于小册的学习者大多初次接触DDD或者对DDD的了解不是特别深刻,因此为了让大家更好的熟悉DDD的编码风格与规范,Demo讲解部分的文章将以能力分层架构 (分支:mater) 做解析。

阅读完能力分层架构后,你也可以自行将分支切换至v0.0.2-SNAPSHOT学习灰度分层架构,相信你会有不一样的体会。

ddd-demo's People

Contributors

louyanfeng25 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ddd-demo's Issues

博主,您好

博主您好,我在掘金看了您写的DDD文章并发现了demo,非常精彩,不过我在对比文章中的工程结构和demo的工程结构发现有些地方对不上,比如domain下并没有adapter,还有聚合根在domain中也是没有的,一点点有疑惑,还望您不要介意,特别感谢您能给出这么好的案例让我们学习。

我们之间DDD的不同之处

我也在探索DDD的一种架构我发现我们之间大致是一致的架构 不过有略微的差别, 特此来讨论一下。
1.我在书中看到domain实体的属性不对外提供getter/setter方法, 只在构造时成立,在构造时通过调用内部private的 set方法来校验参数。(由于在基础层需要把 do 对象转为po对象, 我还是提供了getter方法,目前不知道有什么更好的方案)
2.我把vo与feignclient 提出单独的 rpc层 ,由 api层引用 , 这样可能对我后续微服务组成 引入的代价较小, 以及方便异构服务。
3.我设想是否引入 spring-boot时 应该 按模块引入, 比如 domain模块只引入 依赖导致需要的模块 , api模块引入web模块 (但是还没实现)
4.在领域事件这方面我还没有实现,想要参考您的代码。
以上, 感谢您的阅读,期待您的回复。

关于UserApplicationService craete和updateUserName疑问

博主,您好,最近看了下代码,有个不是很懂的地方还请麻烦指教下
UserApplicationService 里面有craete和updateUserName,为什么create 会用到UserCreateAbility去做业务处理,而updateUserName不需要用Ability

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.