您的位置:首页 > 其它

领域驱动设计有感

2016-02-17 00:00 239 查看
一、领域、软件

什么是领域?

领域可以理解为业务,要解决的问题,要实现什么东西,遇到的困难,可能出现的问题,所有该遵守的规章制度。

软件和领域的关系

让软件成为领域的反射(映射);
软件需要体现领域里重要的核心概念和元素,并精确实现它们之间的关系;
软件需要对领域进行建模。

领域模型?

不是一幅具体的图,它是那幅图要极力去传达的那个思想。是一个抽象的东西。它也不是一个领域专家头脑中的知识,而是一个经过严格组织并进行选择性抽象的知识。

学习领域驱动设计的原则的目的

增进对领域内复杂问题进行建模和实现的开发过程能力。领域驱动设计结合了设计和开发实践,展示了设计和开发如何协同工作以创建一个更好的解决方案。优良的设计会加速开发的过程,而开发过程中的反馈也会进一步优化设计。

软件和领域要结合的意义

软件的最终目的是去解决真实领域中的业务问题,所以它必须和领域完美结合。

二、通用语言

为什么需要通用语言

软件开发人员 和 领域专家 在讨论问题时,会出现交流障碍,如软件开发人员面对问题和业务可能想的都是类、对象、方法等;而领域专家可能会用术语去描述和讨论,对于外行来说很难理解。两者交流互相理解上可能会有很大的偏差,这时就需要通用语言来解决这个问题。
领域驱动设计的一个核心的原则是使用一种基于模型的语言。因为模型是软件满足领域的共同点,它很适合作为这种通用语言的构造基础。使用模型作为语言的核心骨架。
由软件架构师、开发人员和领域专家构成的开发团队,需要一种语言来统一它们的行动,以帮助它们创建一个模型,并使用代码来表现模型。

通用语言是什么?

通用语言不只是模型,还可以是UML图、文档等表示。总之,不管是软件开发人员、设计人员 或是 领域专家等,大家使用通用语言说一个东西大家都知道是什么,不会有太多的理解偏差,大家都认为是统一的一个正确的东西。

三、模型驱动设计

1、实体

必须拥有标识符区分唯一。标识符不一定就是我们理解的数据库的表id,可以是模型自动产生ID;可以是数据库表的一个主键;可以是多个属性组合构成唯一标识符。

2、值对象

为什么需要值对象

因为把所有对象都看成实体,而且每一个实体都必须要有一个唯一标识符,我们就需要仔细的考虑来决定由什么构成标识符,因为一个错误的决定可能会让对象拥有相同的标识,而这并不是我们所预期的;另一方面,将所有的对象视为实体也会带来隐含的性能问题,因为需要对每个对象产生一个实例。

值对象的特点

1)、我们对某个对象是什么不感兴趣,只关心它拥有的属性。用来描述领域的特殊方面、且没有标识符的一个对象,叫做值对象;
2)、值对象没有标识符;
3)、如果值对象是可共享的,那么它们应该是不可变的。值对象应该保持尽量的简单;
4)、值对象可以包含其他的值对象,它们甚至还可以包含对实体对象的引用。

3、服务:

举例

为了从一个账户向另一个账户转钱,这个功能应该放到转出的账户还是在接收的账户中?感觉放在这两个中的哪一个也不对劲。把这样的功能放入实体或者值对象都会导致混乱,因为那些对象的立场将变得不清楚。当这样的行为从领域中被识别出来时,最佳实践是将它声明成一个服务。
一个服务可以将服务于实体和值对象的相关功能进行分组。

4、模块:

为什么使用模块

1)、对一个大型的复杂项目而言,模块被用来作为组织相关概念和任务以便降低复杂性的一种方法。
2)、跟代码质量有关,将高关联度的类分组到一个模块以提供尽可能大的内聚。在设计中使用模块是一种增进内聚和消除耦合的方法

5、聚合:

使用聚合的目的

保持数据一致性和强化不变量。

什么是聚合

每个聚合有一个根。这个根是一个实体,并且它是外部可以访问的唯一的对象。根可以保持对任意聚合对象的引用,并且其他的对象可以持有任意其他的对象,但一个外部对象只能持有根对象的引用。如果边界内有其他的实体,那些实体的标识符是本地化的,只在聚合内有意义。
聚合内的对象可以被允许持有对其他聚合的根的引用。

6、工厂:

帮助封装复杂的对象创建过程。提供一个封装了所有复杂组装的接口,客户程序将不再需要引用要初始化的对象的具体的类。

7、资源库

使用资源库的目的:

封装所有获取对象引用所需的逻辑。领域对象不需处理基础设施,以得到领域中对其他对象的所需的引用。只需从资源库中获取它们,于是模型重获它应有的清晰和焦点。

资源库会保存对某些对象的引用。当一个对象被创建出来时,它可以被保存到资源库中然后以后使用时可从资源库中检索到。如果客户程序从资源库中请求一个对象,而资源库中并没有它,就会从存储介质中获取它。换种说法是,资源库作为一个全局的可访问对象的存储点而存在。

让客户程序保持对模型的关注,把所有的对象存储和访问细节委托给资源库。
工厂与资源库的关系:

工厂关注的是对象的创建,而资源库关心的是已经存在的对象。资源库可能会在本地缓存对象,但更常见的情况是需要从一个持久化存储中检索它们。对象可以用构造函数创建,也可以被传递给一个工厂来构建。从这个原因上讲,资源库也可以被看作一个工厂,因为它创建对象。不过它不是从无到有创建新的对象,而是对已有对象的重建。我们将不把资源库视为一个工厂。工厂创建新的对象,而资源库应该是用来发现已经创建过的对象。。当一个新对象被添加到资源库时,它应该是先由工厂创建过的,然后它应该被传递给资源库以便将来保存它。

四、战略

1、上下文:

模型的范围。

2、持续集成

是基于模型中概念的集成,然后再通过测试实现。任何不完整的模型在实现过程中都会被检测出来。持续集成应用于界定的上下文,不会被用来处理相邻上下文之间的关系。
在代码实现过程中对模型发现新的问题或不足,进而对其进行的完善。

3、上下文映射(Context Map

是指抽象出不同界定上下文和它们之间关系的文档。它的重要之处是让每个在项目中工作的人都能够得到并理解它。
对不同模型之间关系和联系的说明,可以是图表,也可以是文档等形式。

4、共享内核

共享内核的目的是减少重复,但是仍保持两个独立的上下文。对于共享内核的开发需要多加小心。
(共享重复功能和代码,两个团队在使用共享时,都要小心翼翼,并且在进行集成的时候都要进行测试。)

客户-供应商:

5、顺从者:

客户团队遵从供应商团队的模型,完全顺从它。这和共享内核很类似,但有一个重要的不同之处。客户团队不能对内核做更改。他们只能用它做自己模型的一部分,可以在所提供的现有代码上完成构建。

6、防崩溃层:

(防止外部模型对客户端模型的修改,而建立起来的防崩溃层,在两个系统之间做转换。)这个层在两个域和语言之间扮演双向转换器,它最大的好处在于可以使客户端模型保持纯洁和持久,不会受到外部模型的干扰。(转换器)

如何实现防崩溃层?

(将防崩溃层看成是客户端模型提供的一个服务,让服务来处理所需要的转换。)

7、独立方法模式

(独立开发的模型)独立方法模式适合一个企业应用可由几个较小的应用组成,而且从建模的角度来看彼此之间有很少或者没有相同之处的情况;独立开发的模型是很难集成的,不会回到集成系统。

8、开放主机服务:

解决的问题:
当一个子系统要和其他许多子系统集成时,为每一个子系统定制一个转换器会使整个团队陷入困境。会有越来越多的代码需要维护,解决这一个问题的方法是,将外部子系统看作服务提供者当需要做出改变时,根据情况调整服务。

什么是开放主机服务?

定义一个能以服务的形式访问你子系统的协议。开放它,使得所有需要和你集成的人都能获取到。然后优化和扩展这个协议,使其可以处理新的集成需求,但某团队有特殊需求时除外。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  领域驱动设计