浅析领域驱动设计

1.概要

DDD(Domain-driven design,模型驱动设计)是一种软件设计的指导思想,而非固定的一套公式化开发模板(这样就会导致网络上出现各种基于自己或业务上的理解而产出的DDD落地的实现,会让很想学习的开发者迷茫)。在项目的全生命周期内,所有岗位的人员都基于对业务的相同的理解来展开工作。所有人员站在用户的角度、业务的角度区思考问题,而不是从一开始就站在技术的角度去思考。

       在项目初期,需要将领域专家引入到团队中。那什么是领域专家呢?他应该是谁?领域专家是指对业务领域非常熟悉(或在该业务领域耕耘了很多年)。他可以是团队中的任何人,项目经理、产品经理、架构师等等都可以是领域专家,在需求分析阶段大家都需要对需求整体进行评估。团队需要思考这几个问题,是否需要使用DDD?现有的团队人员是否能支撑起DDD?任何技术或者设计都需要整体的评估,而不是一味地去迎合。

       接下来让我们看看什么是领域驱动设计。

f9a02b64913bf961f507459bd2dc057f.png

1.1需求分析

需求分析的方式有很多,例如:用例法,四色建模法。其目的就是为了去建立领域模型的认知。以上两种方法可能会有些抽象,在项目前期与客户沟通过程属于需求分析层面该如何去做。就需要一种统一的一种规则,需要统一语言。接下来就是介绍Domain Story Telling这个概念(这个概念是由domainstorytelling.org网站提出)。包含下图的四个部分。

be7b8d234da0a878348dae28768902fe.png

由项目经理或产品经理通过这四种概念对需求进行梳理,通过这种方式可以很清楚直白的表达出业务场景。那么这四个部分各代表什么含义呢?

  • Pictograms and Vocabulary(象形图和词汇)

    • 1.Actors(角色),(故事场景的参与者,故事指的是功能点)。

    • 2.WorkObjects(参与者与参与者之间传递的内容,或需要呈现的内容称为工作对象)。

    • 3.Acivities(代表的Actors和WorkObjects之间关系,用线的方式来表示)。

    • 4.Annotations(所有流程的注解)。

基于以上概念画出来的图大概是这样,图中大致描述的是电商购物的一个流程分析。

a70b6d38801c194f4c39208c053a6f90.png

以商城购物系统为例。

(1)用户查看商品,向购物网站发送商品列表请求信息。

ba8483a89d6184aaedac492ca047c506.png

(2)购物网站响应商品信息给客户。

e82d0242206f65cce033dde6a985b2e1.png

(3)用户选择商品、购买,发送购买商品请求

b8701f14a5722ebcbe2bccd3f44e3c67.png

(4)购物网站响应订单信息给客户。此时订单是未支付的。

(4.1)用户拿到订单信息之后,开始支付。发送支付请求。

60f35d752ec33c869e30ca5562b8c363.png

(5)购物网站根据用户提供的支付信息,去(银行系统)对应的银行账户中进行扣款。

(5.1)扣款成功之后,再将扣款成功的订单信息返回给购物网站。

621dc5023b0ea1f02d81cf3ef4913a02.png

(6)购物网站拿到扣款成功的订单信息之后,开始通知仓库管理员准备发货。(6.1)并且通知用户,扣款成功购物网站准备发货了。

320204024b04c7350faca94206629214.png

(7)仓库管理员拿到货物之后打包发送给快递员。

4506dda7303076035ccdeed18d5d3f21.png

(8)快递员送货上门给客户。

8fa96f71fe87c119a08ad1579710ab95.png

基于以上的分析,大家可以清楚的了解到商城购物的整个环节。

1.2领域分析

领域(Domain ) :一个组织做的事情(举个比较狭隘的例子,阿里这个组织做的事情就是做电商)。

子域

  • 核心域:解决项目核心问题,和组织业务紧密关联。

  • 支撑域:解决项目的非核心问题,则具有组织特性,但不具有通用性。

  • 通用域:通用特性,没有组织特性。

  • 关心的业务重点不同,领域的划分也不同。

d2f4aa793dee1788d62b251c90f963c5.png

项目初期应考虑的是如何领域建模,用业务语言去描述和构建系统。而不是用技术语言,去思考代码怎么写。技术是服务于业务的脱离业务谈技术或者架构、设计都是空谈。

(1)商品浏览核心域

(2)选择购买商品、支付订单

(3)订单支付,银行交互

(4)发货、仓库管理

(5)配送

目前我们暂时先把购物到配送整个过程划分为五个子域,为什么不是四部分?为什么不是三部分?这个没有明确的标准取决于分析者的当前对业务的理解,站在现有的角度去分析领域边界。并不是说谁做就会更好,符合当前场景下的分析即可。那么划分领域的原则是什么呢?原则是业务并不是功能,围绕的是业务的走向划分而不是以业务的功能点划分。

有了领域边界之后,就开始绘制领域的边界图。那么又会引出新的问题,边界和边界之间存在什么样的关系?是如何交互的?

329e5d7f04431c75e2f8e140d69f7d39.png

站在系统的角度从商品的查询到最终的发货是一个整体的流程。

(1)查询商品的边界和订单的数据做交互(2)订单需要跟支付、仓库做交互(3)仓库跟物流送货做交互那么为了让领域的内聚性更强,会需要去对领域做一个保护。保护手段有三种:防腐层(ACL)、开放主机服务(OHS)、发布语言(PL)。

防腐层(ACL)

通过适配器,桥接模式、外观模式对于访问操作的一种保护。查询商品和订购商品之间的交互是通过一个接口来实现的。定义这个接口是为了不影响别人是需要做一个处理,这个接口不会因为你的领域类的变化而影响接口的定义,我就不会去关心你的内部实现了只考虑在接口层面怎么去交互。接口的表现形式有很多种,在项目中可以是一个接口,在多个项目中可以是一个协议。例如reset api也是一种接口的实现,OSH/OL相当于就是做两个根本不在一起的服务进行交互的一种方式。ACL可以理解为它是一种接口(Interface)层面的定义,D和U就是Down和UP用于区分上下级的关系。以查询商品和订购商品(订单)举例,如果需要做防腐层应该在哪个边界中去做呢?答案是在查询商品,因为不管你商品是什么样的,对于订单来说查询商品属于低层。而对于PL(订购支付)来说就不是了,订购支付属于高层所以订购商品需要主动去做防腐处理。

1.3 Domain Design

b96e7be5ac874701bcd0a1d394d5a2bc.png

(领域建模工具,推荐使用:StarUML,或微软的Viso)

BoundedContext(界限上下文)https://thedomaindrivendesign.io/bounded-context/

Aggregate(聚合根)

聚合根相当于领域中的一个大对象,它其实是由多个Entities和多个Value Obiect组成。它是操作具体业务流程中的关键点,它会由创建它的方法比如说Factories当然也可以去new。

Entities

Entities是有id的唯一标识的,有状态的对象。比如说商城中订单就是这样一个概念。

Value Obiect

是一个无状态的值对象,订单中包含的那些数据可以看作成值对象,例如收货信息address无论这些字段的数值如何改变都不会影响订单的状态而发生改变,只会影响数据不会影响状态。

Services

在Entities满足不了需要的情况下,它操作的都是无状态的数据对象和逻辑。需要先考虑这两条规则。例如转账功能,有AB两个账户,AB都有一个Entities对象,那么谁转账给谁呢?如果在Entities做一个转账好像又不是那么合理,所以会提出一个转账的Services,需要传递两个账户的Content来完成转账的服务。不能在Entities体现这个业务,这个业务是无状态的,这个业务不会去影响Entities的状态只是去做了一个业务逻辑的处理。这种情况下是可以用Services去做的。在DDD中需要弱化Services,大家不要把领域模型花了那么大心思去分析的业务,又大部分通过Services去实现成为了一个数据驱动的开发方式上。所以在做领域设计的时候大家一定要想清楚当时定义的意思和作用。

DomainEvents

因为Entities是有生命周期的且有状态改变的,它很多业务的一些触发条件都是因为这些状态改变而触发的,所以这个领域事件可以关联很多业务的执行逻辑。例如:订单支付完成付款之后,是需要根银行进行交互的,当银行将订单数据返回给商城之后。需要触发两个事件,第一个通知用户,第二个通知仓库管理员。这两件事情的完成都是需要基于支付完订单之后通知给下游的两个领域。所以我们就需要知道领域事件可以作为领域边界触发的一种行为,也可以立即为是解耦的一种方式。如果用领域事件的方式去实现业务那么可以拆分的更细。DomainEvents结合事务的一个分享。分布式事务里的事务消息问题,我们是把一个业务划分为主次的,这个业务关系是相对的。以银行扣款支付成功之后触发两条业务线为例子,什么是主呢?银行的消息提醒给你已经支付成功了这个业务,这是一个主业务,那么它的延申业务有两个(1)通知仓库管理员去发货(2)通知用户支付成功。在实现业务的时,接收银行返回支付状态改变的时候去触发两个事件给延申业务。站在事务的角度上来说,需要满足主线的业务事务提交两个延申的业务,提交之后就不做管理了成功就成功失败就失败,主线就是主线延申就是延申。本地事务提交了才会发送事务消息。事务消息发送完成之后,由两个订阅者去完成各自的业务逻辑,如果失败了也可以通过事务消息来做重复的事务补偿。

Factories

是为了创建Entities和Aggregate的对象,Aggregate实际上也是一个Entities对象,Aggregate只是一个概念实际对应的还是一个对象。具体的实现是Entities、Value Obiect、Services、DomainEvents、Factories、Repositories。而BoundedContext、Aggregate是抽象的概念。

Repositories

代表的是数据操作的资源和方法。比如说:订单信息最终还是要落库的,那么就会涉及到数据库操作那么就需要一个数据库操作的对象。让领域不关心数据的操作。

1.4UML(统一语言)

f30ca723f76ef9bc8b341e541ed6c615.png

(看字面意思就能懂的直接略过...)

组合:两个类的对象生命周期是关联的。

聚合:其他业务也可能包含同样的对象。

1.5 实践

COLA(COLA是阿里巴巴基于领域模型实现的一套服务端的框架)

2a1ab14c97ea652c07621e76fdb7d57e.png

1.6 Specification introduction(规范介绍)

121a8562bc12b99bdcc794fba059fd49.png

1.7GIT Manager(Git代码库版本管理)

5816d34e76b3f3f7f159ada18ab46ec6.png

1.8Test(测试环节)

cbaf0e52d49515ed1b91e3b7b460ab5a.png

单元测试:主要测试的是业务领域模型的逻辑。为什么要测试它呢?因为在做的时候我们的领域是不需要数据的,只要测试通过表示系统的关键业务没有出问题。

性能测试:根据在设计系统的时候,需要设置指标比如系统支撑的最大上限是多少,检测是否满足性能指标。性能测试的前提是在一定的资源下去做的,如果不断的增加服务器数量也是能达到性能指标的。

功能测试:大部分项目中的常见的测试,通过测试用例来验证功能是否可用。还有集成测试和回归测试。

2.Ref

https://domainstorytelling.org/#dst-ddd

https://www.wps.de/modeler/index.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SDIO是一种用于连接多种设备的接口标准,包括Wi-Fi等无线网络设备。SDIO接口Wi-Fi驱动程序是用来管理和控制SDIO模块连接Wi-Fi设备的程序。Wi-Fi驱动程序通常是由设备制造商或操作系统供应商提供的,它们可以针对特定的SDIO模块和Wi-Fi设备进行定制。驱动程序管理SDIO接口与Wi-Fi设备的通信,控制数据流和网络连接以及提供对Wi-Fi设备的配置和监视功能。 在SDIO接口中,Wi-Fi设备一般作为一个SDIO卡出现,并通过SDIO总线与主处理器通信。因此,SDIO接口Wi-Fi驱动程序需要充分考虑SDIO总线和Wi-Fi设备之间的交互,并提供相应的操作和处理流程。常见的SDIO接口Wi-Fi驱动程序包括驱动层和协议层两部分。驱动层主要负责设备驱动程序的加载和卸载,以及控制SDIO总线与Wi-Fi设备之间的基本交互。协议层则实现与Wi-Fi设备之间的高级通信协议和数据传输,如TCP/IP协议栈、接入控制和传输协议等。 SDIO接口Wi-Fi驱动程序的设计和实现需要考虑多方面的因素,如SDIO总线的带宽和时序控制、Wi-Fi设备的固件和驱动程序兼容性、网络连接和性能要求等。通常需要经过严格的测试和优化才能实现良好的性能和稳定性。 总之,SDIO接口Wi-Fi驱动程序是一项关键技术,它的实现对Wi-Fi设备的性能和可靠性都有着重要的影响。需要专业的技术团队和优秀的开发工具支持,才能实现高品质的SDIO接口Wi-Fi驱动程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值