大白话之辩论DDD,阿里面试中台化理解

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 我在最近一年经常听到大家在讨论DDD,而且议论纷纷,大家各抒己见。比如说在某技术微信群讨论,有些人说DDD是噱头,为了搞个业绩(又不是不能跑 😉),还有些表示自己是CRUD Boy 不知道DDD是什么高大上东西。接下来我用大白话来表达我对DDD的看法。

前言

我在最近一年经常听到大家在讨论DDD,而且议论纷纷,大家各抒己见。

比如说在某技术微信群讨论,有些人说DDD是噱头,为了搞个业绩(又不是不能跑 😉),还有些表示自己是CRUD Boy 不知道DDD是什么高大上东西。

接下来我用大白话来表达我对DDD的看法。

现状

  1. 当我们去看招聘网站的时候,会发现有些要求要会领域设计理念。还有些要求会SOA面向服务设计
  2. 在业务发展到一定体量,业务越来越复杂的时候,我们会发现很多的重复劳动,代码堆得像🚯一样,然后大家还在不断往里面丢代码(PS:这样对代码的可扩展性和维护带来很大的麻烦)
  3. 曾经一位小伙伴实现了更新某实体,然后记录操作日志的功能,由于很多方法都会更新到这个实体,他在每个方法里面都去记录修改的日志。这就埋下隐患 (⚠️ 你怎么保证别人在其他方法修改实体的时候,也能记录到操作日志呢,也就是太分散)
  4. 曾经面阿里国际化事业部的时候,被问了问题:你理解的中台化是什么?

大白话辩论

领域设计的作用

Q:针对第一点,不用领域设计行不行?

A:可以不用领域设计,在项目前期的时候,为了将业务快速跑起来,产生价值,这时是顾不上设计的合理性。而且当项目没有到一定的体量,是无法预知到未来会遇到什么变更。当然如果该系统一开始预估的体量就很大,在前期就需要严格去设计好整个架构。


Q:那什么时候需要用上呢?

A: 回到现状第二点,当业务发展到一定体量,业务复杂程度到达一定量的时候,需要用到领域设计来进行改造。这个时候你会发现,大量的代码重复copy,扩展性很差,每次新增需求的时候,都要不断重新开发,这时需要进行领域改造。


Q:第三点导致的原因是什么,怎么解决?

A:本质问题就是,每个方法都会影响到这个实体的更新,导致影响面很大,无法收集到一个点。我们的解决方法就是,将这些更新的地方,全部收集到一个方法里面,然后其他方法只是去调用该变更方法。这样实现日志记录,我只需要去监控一个方法即可!

DDD 精髓

还是大白话讲,就是高内聚,低耦合

PS :我见过很多人上来就是一堆理论,当然理论熟悉也是好事,这样执行起来有条理。

但是🤔 很多知识学到最后就是思想、逻辑、本质,其他都是它幻化出来的东西。这是比较玄学的,顺便讲下我的想法:虚的东西其实是在指引大的方向,比如说企业的愿景,你说它能给业务起作用吗?没有。它是为了给所有行动起到方向的意义。实的东西是为了落地,在落地的时候,又不是用虚的,这样就无法实施。

从实质去讲讲DDD


  • 高内聚,低耦合

Q:为什么需要高内聚,低耦合呢?

我们可以看现状的第三点,其实就是他的变更方法扩散开来了,这样导致很多地方可以去修改方法。所以我们需要去将这些方法抽取到一个方法,这就是高内聚,我一个领域里面,它有什么功能,有什么属性,然后外界是没有这个领域有的功能

Q:低耦合又是啥?

举个常见的例子,A逻辑之后->B逻辑,那么问题来了,哪天我不用B逻辑,我要换C逻辑,但是B跟C我可以根据情况来切换。

有些大聪明站起来说:可以用策略模式。没错,但是它的本质是什么,就是低耦合。A是不知道B,也不知道C的具体实现,它只知道接口,具体它怎么实现,由适配器,什么规则去注入对应的实现类。

Q:既然低耦合的好处是什么?

为了可扩展性,当某天我不用某个中间件,而采用其他中间件,其实我只需要写另一个适配器就解决这个问题。如果代码跟其他中间件强耦合,那GG,你得去改写之前代码,随着中间件越来越多,代码的可读性也会越来越差。


  • 我理解的中台化是什么?

🎄 中台化,SOA面向服务架构,其实都是一个思想,分而治之。一个服务里面,会有这个业务领域对应的相关操作,有对应领域模型,领域对象,值对象,上下文,然后对外提供服务,这体现高内聚,把对应的功能点收拢到一个服务里头进行管理。

🎃 中台概念里头,有个大前台,领域概念里头有个应用层。它作用是干嘛的?是做编排。就是我每个服务都有对应的功能,那么一个业务下来肯定会有很多不同服务来提供功能,需要一个地方来对他们进行编排。

Q:大前台的作用是什么?

在单体服务里头,我们通常写在service里面,像现状第三点,每个方法或者每个服务都有编排任务这样的话就有可能每个服务都会有重复的代码以及相似功能,其实我们需要去抽象出来,变成一个单独的服务,这就是大前台


从理论上讲讲DDD


概念

  1. 领域:领域是相对于业务领域,或者问题域,范围概念。一个领域会包含多个子域,比如说订单域,会有商品、订单等等子域
  2. 限界上下文:既然有范围,那么就有边界,领域之间靠context上下文来进行通讯
  3. 实体、值对象:实体对应PO,值对象,在实体基础上会加上其他属性
  4. 聚合,聚合根:对实体、值对象会进行聚合,聚合根,可以通过这个访问内部实体的东西,不会直接操作跟内部实体
  5. 防腐层 ACL:限界上下文处理外界上下文的时候,需要做业务处理

贫血模型
里面只有属性,但是它的校验、属于它方法放在外面。违反单一原则,封装性比较差的

充血模型
里面包括属性,以及对应的方法实现。这样的好处,开闭原则,以后扩展的话在类里头新增方法。放在外面去做的话,其实是修改,应该减少修改的情况

---

Domain Primitive

在很多业务中,我们面向过程,比如说一个方法(String,String) 参数,他就会有前后顺序,分别代表什么
如果我们把它封装成对象的话,可以减少这样的问题。

原则

  1. 隐形概念显式化 ,比如说聚合根,对于一个东西,它有唯一的标识。如果是前者的话,可以是name,phone等等做标识
  2. 隐式上下文显式化
  3. 封装多对象

这就是为什么有很多值对象,聚合根,entity,其实是为了封装对应类,以及相关的方法,符合开闭原则

DDD分层

在这里插入图片描述

经典分层


接口层、应用层、领域层、基础层

接口层:面向接口,controller

Application 属于编排,就是其他层都封装各自小单元类,他们执行的顺序由应用层来处理

应用层:面向用例,就是会管理各个领域的调用关系,比如说校验完->A领域->B领域

领域层:有领域服务,以及对应子域。处理该领域的业务逻辑

基础层:处理数据库、缓存、第三方等等

在这里插入图片描述

六边形架构


概念上就是以适配器,来达到低耦合的效果,外界通过适配器访问内部接口,向内进行依赖

Q:向内依赖是什么?

越到底层,耦合越高,是我具体实现哪里,比如说我用到什么中间件,这里耦合是最高的。越到外面,就变成抽象接口,适配器,供外部去调用。


依赖倒置分层


基础设施层都是接口,而domain去实现对应接口功能。这样依赖的方向是向外,我用什么中间件,由domian层去解决注入什么类型。

Q:这样设计的好处是什么?

我们很多框架都强依赖第三方框架,比如说mybatis、mq等等中间件
那么它有什么坏处呢?就是当我换其他组件的时候,会改很多东西

domain层设计成接口的好处,就是具体实现不会强依赖其他组件,随时可以另外实现

domain 包含内容 描述
Repositity 映射mapper以及扩展,避免强依赖底层
ACL 防腐层,处理跟外部不一样的东西,比如说协议、api、缓存

按照个人见解画的分层图


在这里插入图片描述

总结

DDD目的是为了高内聚,低耦合。它通过业务领域的划分,然后在领域里面实现对应的功能,实现高内聚。然后通过适配器,依赖倒置,实现低耦合。

在业务体量到达一定程度,还有业务复杂度比较高的项目,是有比较好的扩展性

觉得有帮助的,请关注下博主,感谢~🧧🧧🧧

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
6月前
|
Python 开发工具
2024年Python最全使用Python实现音频双通道分离,2024年最新阿里p7面试难度
2024年Python最全使用Python实现音频双通道分离,2024年最新阿里p7面试难度
2024年Python最全使用Python实现音频双通道分离,2024年最新阿里p7面试难度
|
24天前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
4天前
|
SQL 关系型数据库 MySQL
阿里面试:1000万级大表, 如何 加索引?
45岁老架构师尼恩在其读者交流群中分享了如何在生产环境中给大表加索引的方法。文章详细介绍了两种索引构建方式:在线模式(Online DDL)和离线模式(Offline DDL),并深入探讨了 MySQL 5.6.7 之前的“影子策略”和 pt-online-schema-change 方案,以及 MySQL 5.6.7 之后的内部 Online DDL 特性。通过这些方法,可以有效地减少 DDL 操作对业务的影响,确保数据的一致性和完整性。尼恩还提供了大量面试题和解决方案,帮助读者在面试中充分展示技术实力。
|
30天前
|
消息中间件 存储 canal
阿里面试:canal+MQ,会有乱序的问题吗?
本文详细探讨了在阿里面试中常见的问题——“canal+MQ,会有乱序的问题吗?”以及如何保证RocketMQ消息有序。文章首先介绍了消息有序的基本概念,包括全局有序和局部有序,并分析了RocketMQ中实现消息有序的方法。接着,针对canal+MQ的场景,讨论了如何通过配置`canal.mq.partitionsNum`和`canal.mq.partitionHash`来保证数据同步的有序性。最后,提供了多个与MQ相关的面试题及解决方案,帮助读者更好地准备面试,提升技术水平。
阿里面试:canal+MQ,会有乱序的问题吗?
|
6月前
|
机器学习/深度学习 Python 算法
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
|
26天前
|
消息中间件 架构师 Java
阿里面试:秒杀的分布式事务, 是如何设计的?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴在面试阿里、滴滴、极兔等一线互联网企业时,遇到了许多关于分布式事务的重要面试题。为了帮助大家更好地应对这些面试题,尼恩进行了系统化的梳理,详细介绍了Seata和RocketMQ事务消息的结合,以及如何实现强弱结合型事务。文章还提供了分布式事务的标准面试答案,并推荐了《尼恩Java面试宝典PDF》等资源,帮助大家在面试中脱颖而出。
|
30天前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
30天前
|
关系型数据库 MySQL Java
DDD面试题:DDD聚合和表的对应关系是什么 ?(来自蚂蚁面试)
尼恩,一位40岁的资深架构师,分享了其读者群中关于DDD(领域驱动设计)的面试题及解答,涵盖DDD架构落地、微服务拆分、聚合与MySQL表的对应关系等内容。尼恩通过系统化的梳理,帮助读者在面试中展现强大的技术实力,让面试官印象深刻。此外,他还提供了《尼恩Java面试宝典》等多本技术圣经PDF,助力读者提升架构、设计和开发水平。关注【技术自由圈】公众号,获取更多资源。
DDD面试题:DDD聚合和表的对应关系是什么 ?(来自蚂蚁面试)
|
30天前
|
Kubernetes 架构师 算法
阿里面试:全国14亿人,统计出重名最多的前100个姓名
文章介绍了如何解决“从全国14亿人的数据中统计出重名人数最多的前100位姓名”的面试题,详细分析了多种数据结构的优缺点,最终推荐使用前缀树(Trie)+小顶堆的组合。文章还提供了具体的Java代码实现,并讨论了在内存受限情况下的解决方案,强调了TOP N问题的典型解题思路。最后,鼓励读者通过系统化学习《尼恩Java面试宝典》提升面试技巧。
阿里面试:全国14亿人,统计出重名最多的前100个姓名
|
1月前
|
存储 缓存 NoSQL
阿里面试题:缓存的一些常见的坑,你遇到过哪些,怎么解决的?
阿里面试题:缓存的一些常见的坑,你遇到过哪些,怎么解决的?