保持模型的驱动性
好的开始未必是成功的一半,模型首要是一致性,条款统一没有矛盾。理想的大的企业模型是不现实的,如果我们一直想实现大而全的理想模型,我们将什么也做不成,现实的模型是,将大的模型设计成较小的部分,每个小模型要却来越相对独立,模型的划分没有技巧,只能把相关联并且能形成自然概念的因素放到一个模型里,并且模型之间要定义清晰的边界,模型间关系也应该要精确定义。
1. 界定的上下文
定义模型的范围,画出它的上下文边界,然后尽可能保持模型的一致性。不能因外界的因素影响,我们不能在不同模型间传递对象,也不能在没有边界的情况下,自由地激活行为。这里的上下文,说的很多都是边界。
2. 持续集成
模型不是一开始就被完全定义,先被创建,然后基于对领域新的发现和来自开发过程的反馈等继续完善,基于模型中概念的集成,然后通过测试实现,任何不完整的模型在实现过程中都将被检测出来,通过不断的持续集成,将新增的部分和模型原来配合起来。
3. 上下文映射 (Context Map)
是指抽象出不同界定上下文和它们之间关系的文档,上下文可以作为团队组织的基础, 上下文映射应该写成文档,说明模型之间关系,各层次之间关系。
4. 共享内核 (Shared Kernel)
多个团队如果出现重复性部分,并且令模块十分笨拙,并且无法持续化集成,并且进度缓慢的时候,应该采取共享内核的方式,这种方式修改的时候应该十分小心。
5. 客户供应商 (Customer-Supplier)
如果两个系统之间关系特殊的时候,例如一个严重依赖另一个,并且上下文不同,好比Web商店中“购物系统”与“报表系统”,都是用同一个数据库,但是对用户行为信息,所需要各有不同,这种情况应该使用一方为消费者,一方为供应商的方式交谈,“购物系统”因为供应商,因为用户的行为是通过购物产生的,“报表系统”应为客户,因为它只能调用数据库中数据,这样就可以“报表系统”小组向 “购物系统”小组提出需求,双方协调沟通进行。并且双方都增加测试集合,来保证接口的稳定性。
6. 顺从者
如果客户供应商关系是可行是很好的结果,但是实际情况有很多时候,由于供应商来自很多客户的压力,很难很快实、按时完成客户的项目,这样客户必须选择其他方式来构建自己模型,一种方式是自己实现,还有一种方式是供应商团队的模型很好,可以拿过直接使用,但是前提条件是不能修改模型代码,例如供应商提供组件,客户在组件基础上构建自己应用。
7. 防崩溃层
我们经常碰见所创建的应用与需要和遗留软件,或者和其他独立应用相互交互的情况,由于遗留软件没有使用领域模型技术构建,所以对其使用的模型无法理解,甚至模型模糊不清,所以我们只有建立一个中间层来处理和旧应用的交互,并且也是旧系统的需求。
每一个服务都有一个对应的Façade,对每一个Façade 增加一个 适配器,因为这样会使我们无法清晰的处理繁多功能,如果外部系统复杂,那么在增加一个额外的Façade这样会简化适配器的协议,将它和其他系统分离出来。
8. 独立方法
如果整合难度很大,不值得去做,那么就应该考虑独立方法。独立方法模式,适合企业的应用可由几个较小的应用组成,而且从建模的角度来看,彼此有很少或者没有相同之处的情况。它有自己的需求,从建模和设计的观点来看,它可以由独立实现和独立模型来完成。这种方式应该慎重采用。
9. 开发主机服务
集成两个子系统时,通常它们之间创建一个转换层,当一个系统集成过多子系统时,为每个子系统定制一个转换器会将使整个团队陷入困境,会越来越多的代码维护工作。解决这个问题的办法是,将外部子系统看作服务提供者,所有的子系统访问这个服务,我们这时就不需要转换层了,定义一个能以服务的形式访问你子系统的协议,使的所有想与你集成的人都能获得它,有特殊需求,采用增加协议。例如http协议访问网站,应该就是服务的方式。
10. 精炼
一定要专注核心模型的开发,不要被其他模型所牵连,如果过多精力在其它模型上,那么就与和行业务逻辑的关注想背离了,核心领域的研究和开发不是一朝一夕能完成,需要不断的提炼。一定要关注核心领域模型,就好比软件“心脏”一样。
对于普通子域的实现:
- 购买现成的方案
- 外包:将设计和实现交给其他团队完成,一定要和子域通信接口需要事先定义好。并且要保持沟通。
- 以有模型:使用一个已经有的模型。
- 自己实现模型,这个方案好,但是需要付出额外的精力和金钱。
备注:每个团队都工作于自己的模型,最好每个人都能整个理解模型