使用DDD指导业务设计的一点思考

本文介绍了领域驱动设计(DDD)的核心理念和实践方法,通过餐厅点餐系统的案例,展示了如何从业务逻辑出发,运用DDD进行系统设计。作者强调了模型的重要性,提出“断电思考法”,并探讨了模型、领域模型、上下文、聚合根、实体和值对象等概念。DDD可以帮助开发者更好地理解和设计复杂的业务系统,指导数据库设计、API设计、对象设计和代码组织。
摘要由CSDN通过智能技术生成

领域驱动设计(DDD) 是 Eric Evans 提出的一种软件设计方法和思想,主要解决业务系统的设计和建模。DDD 有大量难以理解的概念,尤其是翻译的原因,某些词汇非常生涩,例如:模型、限界上下文、聚合、实体、值对象等。

实际上 DDD 的概念和逻辑本身并不复杂,很多概念和名词是为了解决一些特定的问题才引入的,并和面向对象思想兼容,可以说 DDD 也是面向对象思想中的一个子集。如果遵从奥卡姆剃刀的原则,“如无必要,勿增实体”,我们先把 DDD 这些概念丢开,从一个案例出发,在必要的时候将这些概念引入。

从纸和笔思考 IT 系统的工作逻辑

让我真正对计算机软件和建模有了更深入的认识是在一家餐厅吃饭的时候。数年以前,我还在一家创业公司负责餐饮软件的服务器端的开发工作,因为工作的原因,外出就餐时常都会对餐厅的点餐系统仔细观察,以便于改进我们自己产品的设计。

一次偶然的情况,我们就餐的餐厅停电了,所幸是在白天,对我们的就餐并没有什么影响。我突然很好奇这家店,在收银系统无法工作的情况下怎么让业务继续运转,因此我饶有趣味的等待服务员来接受我们的点单。

故事的发展并没有超出预期,服务员拿了纸和笔,顺利的完成了点餐,并将复写纸复写的底单麻溜的撕下来交给了后厨。我这时候才回过神来。

软件工程师并没有创造新的东西,只不过是数字世界的砖瓦工,计算机系统中合乎逻辑的过程,停电后人肉使用纸和笔一样合乎逻辑。

合乎现实世界的逻辑和和规则,使用鼠标和键盘代替纸和笔,就是软件设计的基本逻辑。如果我们只是关注于对数据库的增、删、改、查(CRUD),实际上没有对业务进行正确的识别,这是导致代码组织混乱的根本原因。

会计、餐饮、购物、人员管理、仓储,这些都是各个领域实实在在发生的事情,分析业务逻辑,从中找出固定的模式,抽象成计算机系统中对象并存储。这就是 DDD 和面向对象思想中软件开发的一般过程。

你可能会想,我们平时不就是这样做的吗?

现实是,我们往往马上关注到数据库的设计上,想当然的设计出一些数据库表,然后着手于界面、网络请求、如何操作数据库上,业务逻辑被封装到一个叫做 Service 对象上,这个对象不承载任何状态,业务逻辑通过修改数据库实现。

[caption id=“attachment_11342” align=“aligncenter” width=“1518”]一个朴素的应用系统

(一个朴素的应用系统)

一般来说这种方法也没有大的问题,甚至工作的很好,Fowler 将这种方法称作为事务脚本(Transaction Script)。还有其他的设计模式,将用户界面、业务逻辑、数据存储作为一个“模块”,可以实现用户拖拽就可以实现简单的编程,.net、VF曾经提供过这种设计模式,这种设计模式叫做 SMART UI。

这种模式有一些好处。

  • 非常直观,开发人员学习完编程基础知识和数据库 CRUD 操作之后就可以开发
  • 效率高,能短时间完成应用开发
  • 模块之间非常独立

麻烦在于,当业务复杂后,这种模式会带来一些问题。

虽然最终都是对数据库的修改,但是中间存在大量的业务逻辑,并没有得到良好的封装。客人退菜,并不是将订单中的菜品移除这么简单。需要将订单的总额重新计算,以及需要通知后厨尝试撤回正在制作中的菜。

不长眼的新手程序员擅自修改数据片段,整体业务逻辑被破坏。这是因为并没有真正的一个 “订单” 的对象负责执行相关的业务逻辑,Sevice 上的一个方法直接就对数据库修改了,保持业务逻辑的完整,完全凭程序员对系统的了解。

[caption id=“attachment_11344” align=“aligncenter” width=“1366”]简单的增删改查带来业务逻辑问题

(简单的增删改查带来业务逻辑问题)

我们在各个餐厅交流的时候,发现这并不是一个 IT 系统的问题。某些管理不良餐厅,所有的服务员都可以收银,而不是专门的收营员收银;收营员划掉菜品没有更新小计,另外的服务员结账时会发生错误。按照程序设计的语言来说,这些餐厅人员职责不清晰,不符合面向对象的一些原则。

我们吸收到这些业务逻辑到 IT 系统中来,并意识到系统中这里有一些隐藏的模型:

  • 订单
  • 菜品

我们决定,抽象出订单、菜品的对象,菜品不应该被直接修改,而是通过订单才能修改,无论任何情况,菜品的状态变化都通过订单来完成。

复杂系统的状态被清晰的定义出来了, Service 承担处理各个应用场景的差异,模型对象处理一致的业务逻辑。

在接触 Eric Evans 的 DDD 概念之前,我们没有找到这种开发模式的名字,暂时称作为 朴素模型驱动开发。

[caption id=“attachment_11345” align=“aligncenter” width=“1564”]最基本的Repository模式

(最基本的Repository模式)

模型和领域模型

从上面的例子中,模型是能够表达系统业务逻辑和状态的对象。

模型是一个非常宽泛的概念,任何东西都可以是模型,我们尝试给模型下一个定义,并随后继续将领域模型的概念外延缩小。

模型,用来反映事物某部分特征的物件,无论是实物还是虚拟的古人用八个卦象作为世界运行规律的模型;地图用线条和颜色作为地理信息的模型;IT 系统用 E-R 作为对象或者数据库表关系的模型;

我们知道要想做好一个可持续维护的 IT 系统,实际上需要对业务进行充分的抽象,找出这些隐藏的模型,并搬到系统中来。如果发生在餐厅的所有事物,都要能在系统中找到对应的对象,那么这个系统的业务逻辑就非常完备。

现实

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值