实践 DDD 领域驱动设计_第1页
实践 DDD 领域驱动设计_第2页
实践 DDD 领域驱动设计_第3页
实践 DDD 领域驱动设计_第4页
实践 DDD 领域驱动设计_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

说明领域驱动设计最近又火了。概念不断被提及,但是相信对于像笔者一样的很多开发者对于其如何应用都一头雾水。正如《实现领域驱动设计》中作者提到的不同公司的业务能力开发能力和成熟度不一样,DDD为了解决复杂业务为生,并不适合所有的软件项目,对于很多初创公司而言,业务本身就是模糊的,只是需要做出一个MVP(最小可行性产品)来试探商业模式,采用ddd显得过〃重”了一点,反而给团队成员带来额外的负担,所以团队管理者首先应该关注的是软件系统是否得做出DDD投入。不过不管黑猫白猫,能抓到老鼠就是好猫。我们以电商业务来演练和实践ddd的部分理论,并解释ddd的概念。战略设计阶段领域:即业务是属于哪块,电商领域,保险领域,零售领域,又可细化分为子领域。如电商下(订单交易领域、库存领域、会员领域、物流领域....)领域专家:一般指熟悉对应领域的产品经理项目经理子域:子域可细分为核心子域、通用子域和支撑子域,简单理解为哪部分是比较核心的就可称作核心子域,哪些功能偏边缘化叫支撑域。互联网公司的敏捷开发模式的产品研发流程从收集需求、 PRD评审、技术模块拆分这些前期流程。而战略设计即在这个阶段完成,顾名思义侧重于从宏观上对业务进行拆分,和对未来走向的预测。DDD的目的是为了领域专家更好地与开发进行沟通合作,使得代码更好地传达业务规则。最初的需求方可能会提一些凌乱的需求。为了更好地传达规则,领域专家将需求整合提取出领域的概念,技术 /项目管理者一起划分好子域和限界上下文。各方统一所谓的通用语言并在以后的协作中使用。比如电商业务中双方约定好中商家用户和买家用户的概念,用户和账户的概念,交易订单和支付订单、物流订单、售后订单的概念,以实现后期沟通顺畅。最终产出:划分出了哪些子领域、上下文映射图是怎样的。贴一个电商业务的上下文映射图(下单交易上下文为下游,其他皆为上游):而各个上下文的交互方式,即集成限界上下文的方式其实就是我们常说的系统交互方式:RPC调用、REST接口调用、消息队列通信。怎么理解限界上下文和子域的关系?限界上下文:是一个显示边界,领域模型即存在于这个边界之内。在边界内,通用语言有特定明确的意义。ps:是不是觉得每个字都认得,但是不知道表达了什么意思....在理解限界上下文和子域上确实有点费劲。笔者当时的疑惑主要是:为什么要用上下文映射图而不是子域交互图,子域划分出来不就说明边界已经明确了么,为什么还专门搞一个限界上下文的概念。关于限界上下文,贴一下个人理解:接下来要咬文嚼字一些了。1、 从〃限界”二字来说。限界上下文明确了业务范围和职责边界。针对上面问题“子域中不是已经有边界的概念了么”。可以思考一个有意思的事,子域有边界,还是说因为有了边界才有子域。听到过一个非常到位的类比如果没有细胞壁,如何定义细胞质?2、 从“上下文”来说。上下文关注的是两个系统交互时的环境,或者说语境。举个例子:小学是一个子域,中学是一个子域。升学这个事件动作则要上下文表达。通用语言要在限界上下文(语境)中保证其明确意义。举个例子,商家管理上下文中,我们(平台)说的用户指的是商家而不是买家,支付上下文中,我们以支付单为核心,语境无需引入物流单、库存等词汇。通常来说,我们可以近似地认为子域和限界上下文一对应的。战术设计阶段截止到此,我们已经划分好了子域,对开发人员来说,已经拆分好了项目。各个团队可以针对自己的子域进行独立开发了。对于 ddd而言,我们开始进行战术设计阶段。战略设计关心做什么,战术设计则更关心技术实现细节,即:怎么做。先说下ddd中推荐的六边形架构:这里要吐槽一下六边形架构这个命名,搞得好像有六个什么东西一样。其实只是根据视觉形状起的名。现在叫端口与适配器架构。转换一下是这样的严格分层架构:某层只能与直接位于其下方的层发生耦合松散分层架构:允许上方层可以与任意下方层发生耦合。这里采用松散分层架构。也可按依赖倒置原则,基础层依赖领域层的一些东西(常见的就是实体Entity)适配器层:负责接口转换,即是最外层请求处理类,将外部请求转化为内部 API能理解的输入。对于REST接口可能是一个controller类;对于dubbo调用来说是开放出去的provider服务类;对于grpc调用来说,是protobuf请求对象转换处理类;对于消息机制来说,对应的是消息的监听器如此采用端口适配器模式,可以不影响内部服务,只需在适配器层进行增改。尽管大家不知道六边形架构的定义,但相信很多人是这样做的。无须螯述。应用层:负责协调领域层的接口实现前端展示或返回需要。领域层:定义领域实体和逻辑。包括实体、值对象、领域服务、领域事件、资源库。基础层:如数据库相关。实体和值对象实体:有唯一业务标识有自己的业务属性和行为属性可变,有自己的生命周期对象河以有唯一业务标识有自己的业务属性和行为旦定义不可改变二者的关系可总结为:值对象关心对象是什么样的,实体侧重描述对象是哪提到有自己的业务属性和行为这块,想想这不就是我们年轻时说的面向对象编程的思想码?但是回顾一下会发现,这个思想好像被很多人抛诸脑后很久了,定义的对象类都成了一个个的pojo,只有属性和属性对应getter和seter方法,也就是ddd中所说的失血模型。失血模型:只含属性和对应的getter/setter方法,无业务处理逻辑贫血模型:包含不依赖持久化的部分领域逻辑,依赖持久的逻辑被放在领域服务层。充血模型:绝大数业务逻辑都放在其中,包括持久化逻辑。少数不适合的逻辑被提取出来放在领域服务层中。胀血模型:主张不需要领域服务层,把一些业务逻辑都放在模型对象中处理领域服务胀血模型主张把所有的业务逻辑放在模型中处理,但是事实上有些逻辑并不是适合放在某个领域对象中处理。比如1、 领域对象间的转换2、 某些场景下需要多个领域对象作为输入值,结果产生一个值对象。区别于应用层的服务,领域服务处理的是业务逻辑。应用层负责对领域服务处理结果进行渲染和组装返回给前端。ps:针对查询类的操作,建议作为应用层的查询服务单独拎出来,因为查询尝尝涉及到多个维度的查询,或把多个领域对象的查询结果组装成一个返回值对象。举个栗子:订单领域需要向商家(PC端)和买家(APP端),商家端按发货条件时间查询所有买家的订单,操作发货处理售后等流程。买家端完成下单、查询个人订单。在应用层我们抽象三个应用处理出来,公用的查询应用、商家端应用(关联商家权限控制上下文)、买家端应用(关联买家权限控制上下文)。领域事件领域事件即领域业务周期中一些关键行为,关键的定义是其他地方需要依赖此事件推送业务流转。如订单被支付这个事件,需要触发库存扣减、商家待结算账户余额增加等操作。关于领域事件处理方法:跨子域处理常用消息队列发布/订阅模式,同项目处理常用注册事件监听器处理。不多描述。聚合和资源库领域对象之间常常有依赖关系。比如主订单-子订单(商品)项,子订单依附于主订单存在,二者的关系称作聚合,主订单作为聚合根.@DatapublicclassTradeOrderEntity{//订单号StringorderNo;//商品详情ListorderltemDetails;//...}我们通过为每一个聚合选择一个根,并通过根来控制所有对边界内的对象的访问。外部对象只能持有根的引用;由于根控制了访问,因此我们无法绕过它去修改内部元素。所以在ddd中,资源库Repository是面向聚合根操作的,可对多个dao对象的组合使用。@RepositorypublicclassTradeOrderRepository{@AutowiredTradeOrderMappertradeOrderMapper;@AutowiredOrderItemDetailMapperorderltemDetailMapp

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论