《领域驱动设计》基础知识汇总

更新时间:2023-05-14 08:58:16 阅读: 评论:0

《领域驱动设计》基础知识汇总(转)
1. 什么是领域(Domain)
我们所做的软件系统的目的都是来解决一系列问题,例如做一个电商系统来在线销售自己企业的产品;做一个灰度发布平台来提升服务的质量和稳定性。任何一个系统都会属于某个特定的领域,例如:
论坛是一个领域:要做一个论坛,那这个论坛的核心业务是确定的:比如用户发帖、回帖等核心基本功能;
电商系统是一个领域:只要是电商领域的系统,那核心业务就是:商品浏览、购物车、下单、减库存、付款交易等核心环节;
同一个领域的系统都具有相同的核心业务,因为他们要解决的问题的本质是类似的。因此可以推断:一个领域本质上可以理解为一个问题域 。只要确定了系统所属的领域,那么这个系统的核心业务,即要解决的关键问题就基本确定了。通常我们说,要成为一个领域的专家,必须要在这个领域深入研究很多年才行,只有这样才会遇到非常多的该领域的问题,
积累了丰富的经验。
2.界限上下文(Bounded Context)
通常来说,一个领域有且只有一个核心问题,我们称之为该领域的『核心子域』。在核心子域、通用子域、支撑子域梳理的同时,会定义出子域中的『限界上下文』及其关系,用它来 阐述子域之间的关系 。界限上下文可以简单理解成一个子系统或组件模块。
例如:下图是对酒店管理的子域和界限上下文的梳理:
3. 领域模型(Domain Model)
领域驱动设计(Domain-Driven Design)分为两个阶段:
1. 以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然后将这些概念设计成一个领域模型;
2013年春节联欢晚会节目单
2. 由领域模型驱动软件设计,用代码来实现该领域模型;
由此可见,领域驱动设计的核心是建立正确的领域模型。领域模型具有以下特点
1. 对具有某个边界的领域的一个抽象,反映了领域内用户 业务需求的本质 。它属于『解决问题空间』。领域模型是有边界的,只反应了我们在领域内所关注的部分,包括 实体概念(如:货物,书本,应聘记录,地址等),以及 过程概念(如:资金转账等);
2. 提高软件的 可维护性业务可理解性以及可重用性。领域模型确保了我们的软件的业务逻辑都在一个模型中,帮助开发人员相对平滑地将领域知识转化为软件构造;
3. 贯穿软件 分析、设计、开发 的整个过程。领域专家、设计人员、开发人员面向同一个
模型进行交流,彼此共享知识与信息,所以可以防止需求走样,让软件开发人员做出来的软件真正满足需求;要建立正确的领域模型并不简单,需要领域专家、设计、开发人员积极沟通共同努力,然后才能使大家对领域的认识不断深入,从而不断细化和完善领域模型;
4. 为了让领域模型看的见,使用的常用表达领域模型的方式:图、代码或文字;
5. 重要性:领域模型是整个软件的核心,是软件中最有价值和最具竞争力的部分;设计足够精良且符合业务需求的领域模型能够更快速的响应需求变化;
4. 领域通用语言
由软件专家和领域专家合作开发一个领域的模型是有必要的。开发过程中, 开发人员以类、算法、设计模式、架构等进行思考与交流。但领域专家对此一无所知,他们对技术上的术语没有太多概念,只了解特有的领域专业技能,例如:在空中交通监控样例中,领域专家知道飞机、路线、海拔、经度、纬度,他们有自己的术语来讨论这些事情。软件专家和领域专家交流过程中,需要做翻译才能让对方理解这些概念。
领域驱动设计的一个核心原则是使用一种基于模型的语言。使用模型作为语言的核心骨架,要求团队在进行所有的交流是都使用一致的语言,在代码中也是这样,这种语言被称为『通用语言』
5.建模思考的问题:用户需求
『用户需求』不能等同于『用户』,捕捉『用户心中的模型』也不能等同于『以用户为核心设计领域模型』。设计领域模型时不能以用户为出发点去思考问题,不能老想着用户会对系统做什么;而应该从一个客观的角度,根据用户需求挖掘出领域内的相关事物,思考这些事物的本质关联及其变化规律作为出发点去思考问题。
领域模型是 排除了人之外的客观世界模型 ,包含了人所扮演的参与者角色。但是一般情况下不要让参与者角色在领域模型中占据主要位置,否则各个系统的领域模型将变得没有差别,因为软件系统就是一个人机交互的系统,都是以人为主的活动记录或跟踪。例如:
论坛中如果以人为主导,那么领域模型就是:人发帖,人回帖,人结贴,等等;
货物托运系统中如果以人为主导,就变成了:托运人托运货物,收货人收货物,付款人
付款,等等;
以一个货物运输系统为例子简单说明一下。在用户需求相对明朗之后,这样描述领域模型:
一个Cargo(货物)涉及多个Customer(客户,如托运人、收货人、付款人),每个Customer承担不同的角色;
Cargo的运送目标已指定,即Cargo有一个运送目标;
由一系列满足Specification(规格)的Carrier Movement(运输动作)来完成运输目标;
以上描述没有从用户的角度去描述领域模型,而是以领域内的相关事物为出发点,考虑这些事物的本质关联及其变化规律的:
以货物为中心,把客户看成是货物在某个场景中可能会涉及到的关联角色,如货物会涉及到托运人、收货人、付款人;
货物有一个确定的目标,货物会经过一系列的运输动作到达目的地。
以用户为中心来思考领域模型的思维只是停留在需求的表面,而没有挖掘出真正的需求的本质。领域建模时需要努力挖掘用户需求的本质,这样才能真正实现用户需求。
6. 经典分层架构
用户界面/展示层:1)请求应用层获取用户所需的展示数据;2)发送命令给应用层执行用
户的命令
应用层:薄薄的一层,定义软件要完成的任务。对外为展示层提供各种应用功能,对内调用领域层(领域对象或领域服务)完成各种业务逻辑。应用层不包含业务逻辑
领域层:表达业务概念、业务状态信息及业务规则,是业务软件的核心
基础设施层:为其他层提供通用的技术能力,提供了层间通信;为领域层提供持久化机制。
7. 使用的模式
7.1. 总览图
青少年游学
7.2. 关联的设计
关联在领域建模的过程中非常重要,关联的设计可以遵循如下的一些原则:
置若罔闻
关联 i wanted you尽量少。对象之间复杂的关联容易形成对象的关系网,对于理解和维护单个对象很不利,同时也很难划分对象与对象之间的边界;另外,减少关联有助于简化对象之间的遍历;
关联尽量保持 单向 的关联;
在建立关联时,需要挖掘是否存在关联的 限制条件 。如果存在,那么最好把限制条件加到关联上,往往这样的限制条件能将关联化繁为简,即将多对多简化为1对多,或将1对多简化为1对1;
7.3. 实体(Entity)
实体就是领域中需要 唯一标识 的领域概念。因为我们有时需要区分是哪个实体:有两个实体,如果唯一标识不一样,那么即便实体的其他所有属性都一样,也认为他们是两个不同的实体。
学日语哪里好不应该给实体定义太多的属性或行为,而应该寻找关联,将属性或行为转移到其他关联的实体或值对象上。比如:Customer 实体,有一些地址信息,由于地址信息是一个完整的有业务含义的概念,所以我们可以定义一个 Address 对象,然后把 Customer 的地址相关的信息转移到 Address 对象上。如果没有 Address 对象,而把这些地址信息直接放在 Customer 对象上,然后对于一些其他的类似Address的信息也都直接放在Customer 上,会导致 Customer 对象很混乱,结构不清晰,最终导致它难以维护和理解。
7.4. 值对象(Value Object)
mashimaro
并不是每一个事物都必须有一个唯一标识。就以上面的地址对象 Address 为例,如果两个 Customer 的地址信息是一样的,我们就会认为这两个 Customer 的地址是同一个。用程序的方式来表达就是:如果两个对象所有属性的值都相同,我们会认为它们是同一个对象,那么就可以把这种对象设计为值对象
值对象的特征:
值对象 没有唯一标识 ,这是它和实体的最大不同。值对象在判断是否是同一个对象时是
通过它们的所有属性是否相同,如果相同则认为是同一个值对象。在区分是否是同一个实体时,只看实体的唯一标识是否相同,而不管实体的属性是否相同。
值对象是 不可变 的,即所有属性都是只读的走遍美国下载,所以可以被安全的共享。
应该给值对象设计的尽量简单,不要让它引用很多其他的对象。值对象只是一个值,类似(int a = 3)中的『3』,只不过是用对象来表示。值对象虽然是只读的,是一个完整的不可分割的整体,但是可以被整个替换掉:类似(a = 4)把a的值由『3』替换为为『4』,当修改 Customer 的 Address 对象引用时,不是通过 Customer.Address.Street 这样的方式来修改属性,可以这样做:Customer.Address = new Address(…)
7.5. 领域服务(Domain Service)
领域中的一些概念不太适合建模为对象(实体对象或值对象),因为它们本质上就是一些操作、动作,而不是事物。这些操作往往需要 协调多个领域对象。如果强行将这些操作职责分配给任何一个对象,则被分配的对象就是承担一些不该承担的职责,从而会导致对象的职责不明确很混乱。DDD认为领域服务模式是一个很自然的范式用来对应这种跨多个对象的操作。一般的领域对象都是有状态和行为的,而领域服务没有状态只有行为。
领域服务还有一个很重要的功能就是可以避免领域逻辑泄露到应用层。因为如果没有领域服务,那么应用层会直接调用领域对象完成本该是属于领域服务该做的操作,需要了解每个领域对象的业务功能,以及它可能会与哪些其他领域对象交互等一系列领域知识。这样一来,领域层可能会把一部分领域知识泄露到应用层。对于应用层来说,通过调用领域服务提供的简单易懂且意义明确的接口肯定也要比直接操纵领域对象容易的多。
说到领域服务,还需要提一下软件中一般有三种服务:应用层服务、领域服务、基础服务。从以下的例子中可以清晰的看出每种服务的职责:
应用层服务
1. 获取输入(如一个XML请求)
2. 发送消息给领域层服务,要求其实现转帐的业务逻辑
3. 领域层服务处理成功,则调用基础层服务发送Email通知
领域层服务
1. 获取源帐号和目标帐号,分别通知源帐号和目标帐号进行扣除金额和增加金额的操作
2. diapers提供返回结果给应用层
基础层服务
1. 按照应用层的请求,发送Email通知
enhanced是什么意思7.6. 聚合及聚合根(Aggregate,Aggregate Root)
聚合plead定义了一组具有 内聚关系 的相关对象的集合,以及对象之间清晰的所属关系和边界,避免了错综复杂的难以维护的对象关系网的形成。我们把聚合看作是一个修改数据的单元
聚合有以下特点:
1. 每个聚合有一个根和一个边界:根是聚合内的某个实体;边界定义了一个聚合内部有哪些实体或值对象;
2. 聚合根是外部可以保持对聚合引用的唯一元素,负责与外部其他对象打交道并维护自己内部的业务规则。聚合内部的对象之间可以相互引用,但是聚合外部如果要访问聚合内部的对象时,必须通过聚合根开始导航,绝对不能绕过聚合根直接访问聚合内的对象;

本文发布于:2023-05-14 08:58:16,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/108007.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:领域   对象   模型   服务   业务   用户   设计   核心
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图