领域驱动设计

想了解一下什么是领域驱动设计,没想到一大堆新奇的名词汹涌而出,查资料查到手软,仿佛捅了马蜂窝。

一、什么是领域驱动设计

二、领域驱动设计的优缺点

三、领域驱动适用场景

以上三个问题,只能是列出问题,而无答案,变成问题三连。因为我搜了很多文章,都搞不清楚这个所谓的领域驱动是个啥,有啥好处,用在何种场景。所有文章都说了一大堆,包括标题带有“浅析”字样的文章,但我怎么都读不懂,不明就里。

领域驱动设计(Domain-Driven Design,简称DDD),顾名思义,就是由领域,即业务,来主导信息系统的设计。信息系统用于满足业务的需求,而在通常的开发过程中,不管啥业务,基本上开发的套路,系统所采用的架构,都是一样的,比如分层结构,系统分为UI层、逻辑层、服务层、数据持久层等等。这听起来,就好像有点削足适履,因果颠倒了。领域驱动设计反其道而行之,意图立规矩,要技术适应业务,而不是业务适应技术。

具体点,领域驱动设计似乎要实现的是,因应业务的特点来选择合适的架构(据说有一种敏捷开发方法叫水晶方法,特点就是项目类型不同,开发方法就不同,与之点相似)。对于同一领域的信息系统,要千方百计抽象出一个领域层,就是这种业务的核心的、共性的东东。这层东东,对于该种业务来说,是相对稳定、极少变化的,抽象出来,不管你采用什么技术来实现,怎么优化,都不会影响到这一层。而在我们常用的分层架构中,上层依赖下层,而包含业务性的东西,往往处于很下面的层次,里面包含了许多的调用、实现,所以程序重构、优化,往往首当其冲。而领域驱动设计里,不是分层,而是采用六边形架构,领域层处于核心,通过依赖注入来解耦外层对它的影响。

软件系统从来都不是凭空而来,而是以软件的形式解决特定的问题。当我们面临现实世界的复杂问题时,如何以软件的形式落地驱动设计是一套方法论,指导我们将复杂问题进行拆分、拆分出各个子系统间的关联以及是如何运转的,帮助我们解决大型的复杂系统在落地中遇到的问题。

Evic Evans(领域驱动设计的提出者)在著作中将软件系统的设计分为2个部分:战略设计和战术设计。在战略设计层面提出了域、子域、限界上下文等重要概念;在战术设计层面提出了实体、值对象、领域服务、领域事件、聚合、工厂、资源库等重要概念。如图1所示:

【适合场景】
读/写比较大的场景
对查询实时性要求不高的场景
内部状态改变会触发各种数据的同步,如课程完成,课程发布等等等等。。。
外部实现可替换,如mq可以随意替换实现

【不适合场景】:
只有简单CRUD的业务,没有重的业务逻辑,不适合搞那么复杂,因为没必要抽出domain层

3、GRASP(通用职责分配软件模式)
GRASP(General Responsibility Assignment Software Patterns,通用职责分配软件模式)

说到模式,最有名的莫过于GOF设计模式了。按我的理解,这里的GRASP,是系统分析阶段的建模模式,GOF是系统设计、开发阶段的设计模式。

GRASP能够帮助我们理解基本对象的设计,提高面向对象设计(OOD)的觉悟。GRASP的9个模式企图解决的问题只有一个:如何建模,如何划分、设计对象,一个系统应该有多少个对象,每个对象应该包括哪些功能,不应该包括哪些功能,对象之间应该建立怎样的关系。通用职责分配软件模式,顾名思义,一个对象应该实现哪些功能由其承担的职责决定,即职责驱动对象设计。

创建者(Creator)
信息专家(Information Expert)
低耦合(Low coupling)
控制器(Controller)
高内聚(High Cohesion)
多态性(Polymorphism)
纯虚构(Pure Fabrication)
间接性(Indirection)
防止变异(Protected Variations)

领域驱动设计
设计阶段,除了设计模式,还有设计SOLID原则,大家耳熟能详。它们与上面的GRASP有相似的地方。

Single Responsibility Principle:单一职责原则
Open Closed Principle:开闭原则
Liskov Substitution Principle:里氏替换原则
Law of Demeter:迪米特法则 Interface
Segregation Principle:接口隔离原则
Dependence Inversion Principle:依赖倒置原则

4、CQRS(命令查询职责分离)
CQRS(Command Query Responsibility Segregation,命令查询职责分离)。意思就是查询与命令(增删改)分开,各使用不同的模型。

一般来说,我们对数据库的操作CRUD,都用同一种模型。而CQRS 则做了改变,将这个模型拆分成命令和展示两部分,分别叫做 Command 和 Query。把模型拆开来,这意味着可以用不同的逻辑进程、不同的硬件来做这两部分事情了。一个 WEB 上的例子,用户查看页面的时候使用查询模型;而如果要改变数据,这种改变会解析成若干命令模型来执行操作,操作完毕后通知状态的更新。

好处是在操作层面上读写分离,提高针对性,降低复杂度。

5、关注点分离
关注点分离(Separation of concerns,SOC)是处理复杂性的一个原则。由于关注点混杂在一起会导致复杂性大大增加,所以把不同的关注点分离开来,分别处理就是处理复杂性的一个原则,一种方法。

日常生活和生产中,关注点分离是广泛使用的、解决复杂问题的一种系统思维方法。大体思路是,先将复杂问题做合理的分解,再分别仔细研究问题的不同侧面(关注点),最后综合各方面的结果,合成整体的解决方案。

关注点分离也是计算机科学和软件工程在长期实践中确立的一项方法论原则。模块化就是其中的代表。同时它也是面向对象的程序设计的核心概念。


2021.05.10
我觉得微服务架构也算是关注点分离的一个实例。微服务架构,将原本庞大的单体项目,分解成若干个小系统,解决了问题的复杂性。

领域驱动设计
领域驱动设计的优点和挑战
说说领域驱动设计和贫血、失血、充血模型
领域驱动设计详解:是什么、为什么、怎么做r> 六边形架构和分层架构的区别
GRASP模式概述
DDD 中的那些模式 — CQRS


2022.07.05
我感觉,如果真的存在一个所谓领域共性的东西,那它就不应该跟其他代码挤在一个项目里,而是采用微服务,或者SOA架构,将领域层单独做成一个服务。把业务共性的东西,放在每个项目里,本身就不是设计之道,反而去扯什么信息开发技术适应业务,根本就是搞错了方向。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年6月4日
下一篇 2022年6月4日

相关推荐