领域驱动设计-读书笔记-第十六章-大型结构

复杂系统面临的真实问题

背景

硅谷一家小设计公司签了一份为卫星通信系统创建模拟器的合同。工作进展得很顺利,他们正在利用MODEL-DRIVEN DESIG来进行开发。

为了澄清模型中的复杂关系,他们已经把设计分解为一些在规模上便于管理的内聚MODULE,于是现在便有了的很多MODULE。

问题

在这种情况下,开发人员要想查找某个功能,应该到哪个MODULE中去查呢?如果有了一个新类,应该把它放在哪里?这些小软件包的实际意义是什么?它们又是如何协同工作的呢?而且以后还要创建更多的MODULE。

开发人员互相之间仍然能够进行很好的沟通,而且也知道每天都要做什么工作,但项目领导者却不满足这种一知半解的状态。他们需要某种组织设计的方式,以便在项目进入到更复杂的阶段时能够理解和掌控它。

解决方案

将设计放到一个结构中。对整个系统重新分层,整个模拟器将被看作由一系列层组成,这些层分别对应于通信系统的各个方面。同时按照新的结构来重构代码。

总结

1)在一个大的系统中,如果因为缺少一种全局性的原则而使人们无法根据元素在模式(这些模式被应用于整个设计)中的角色来解释这些元素,那么开发人员就会陷入“只见树木,不见森林”的境地。

2)我们需要理解各个部分在整体中的角色,而不必去深究细节。

“大型结构”是一种语言,人们可以用它来从大局上讨论和理解系统。它用一组高级概念或规则(或两者兼有)来为整个系统的设计建立一种模式。这种组织原则既能指导设计,又能帮助理解设计。另外,它还能够协调不同人员的工作,因为它提供了共享的整体视图,让人们知道各个部分在整体中的角色。

模式:EVOLVING ORDER (有序演化)

很多开发人员都亲身经历过由于设计结构混乱而产生的代价。为了避免混乱,项目通过架构从各个方面对开发进行约束。

无论架构是面向技术的,还是面向领域的,如果其限定了很多前期设计决策,那么随着需求的变更和理解的深入,这些架构会变得束手束脚。

因为规避混乱,做了很多限定,但是过多限定,可能会产生如下问题:

一个没有任何规则的随意设计会产生一些无法理解整体含义且很难维护的系统。但架构中早期的设计假设又会使项目变得束手束脚,而且会极大地限制应用程序中某些特定部分的开发人员/设计人员的能力。很快,开发人员就会为适应结构而不得不在应用程序的开发上委曲求全,要么就是完全推翻架构而又回到没有协调的开发老路上来

问题并不在于指导规则本身应不应该存在,而在于这些规则的严格性和来源。如果这些用于控制设计的规则确实符合开发环境,那么它们不但不会阻碍开发,而且还会推动开发在健康的方向上前进,并且保持开发的一致性。

解决方案如下:

概念上的大型结构随着应用程序一起演变,甚至可以变成一种完全不同的结构风格。不要依此过分限制详细的设计和模型决策,这些决策和模型决策必须在掌握了详细知识之后才能确定根据实际经验和领域知识来选择结构,并避免采用限制过多的结构,如此可以降低折中的难度。真正适合领域和需求的结构能够使细节的建模和设计变得更容易,因为它快速排除了很多选项。

模式:SYSTEM METAPHOR (系统隐喻)

隐喻思维在软件开发(特别是模型)中是很普遍的。但极限编程中的“隐喻”却具有另外一种含义,它用一种特殊的隐喻方式来使整个系统的开发井然有序。

比如,把高楼大厦的防火墙隐喻成软件的防火墙。

作用:

SYSTEM METAPHOR(系统隐喻)是一种松散的、易于理解的大型结构,它与对象范式是协调的。由于系统隐喻只是对领域的一种类比,因此不同模型可以用近似的方式来与它关联,这使得人们能够在多个BOUNDED CONTEXT中使用系统隐喻,从
而有助于协调各个BOUNDED CONTEXT之间的工作。

当系统的一个具体类比正好符合团队成员对系统的想象,并且能够引导他们向着一个有用的方向进行思考时,就应该把这个类比用作一种大型结构。围绕这个隐喻来组织设计,并把它吸收到UBIQUITOUS LANGUAGE中

模式:RESPONSIBILITY LAYER (按照职责分层)

什么是层?

所谓的层,就是对系统进行划分,每个层的元素都知道或能够使用在它“下面”的那些层的服务,但却不知道它“上面”的层,而且与它上面的层保持独立。

如何分层?

在一个具有自然层次结构的模型中,可以围绕主要职责进行概念上的分层,这样可以把分层和职责驱动的设计这两个强有力的原则结合起来使用。

示例 深入研究运输系统的分层

他们发现在讨论运输时间表(安排好的货轮航次或火车班次)时不需要涉及所运输的货物。而当讨论对一个货物的跟踪时,如果不知道它的运输信息,那么就很难进行跟踪。概念依赖性是非常清楚的。团队很容易就区分出两个层:“作业”层和这些作业的基础层(他们把这个层叫做“能力”层)。

能力层说明:

这个层反映了公司在执行作业时所能利用的资源。Transit Leg就是一个典型的例子。人们为货轮制定航程时间表,货轮具有一定的货运能力,这个能力有可能被完全利用,也有可能未被完全利用。

这家运输公司中,需要与客户保持长期关系,而且大部分业务都来自回头客。考虑到企业用户的这些意图,Customer应该属于“能力”层。

如下,继续进行演进:

在很大程度上,最初的两个层主要考虑的是当前的情况或计划。但Router(以及其他很多未在图中画出的元素)并不是当前的作业或计划的一部分。它是用来帮助修改这些计划的。因此团队定义了一个新的层,让它来负责决策支持(Decision Support)。

Router是一个SERVICE,能帮助预订代理(booking agent)选择运送货物的最佳路线。因此Router明显属于决策支持层。

领域专家们刚刚告诉我们一些针对特定类别危险品的航线约束。有些危险品在某些货轮或港口上是禁止装载的。我们必须使Router遵守这些规则。

总结:

当对层进行删除、合并、拆分和重新定义等操作时,应寻找并保留以下一些有用的特征。
1)场景描述。层应该能够表达出领域的基本现实或优先级。选择一种大比例结构与其说是一种技术决策,不如说是一种业务建模决策。层应该显示出业务的优先级。
2)概念依赖性。“较高”层概念的意义应该依赖“较低”层,而低层概念的意义应该独立于较高的层。
3)CONCEPTUAL  CONTOUR。如果不同层的对象必须具有不同的变化频率或原因,那么层应该能够容许它们之间的变化。
4)在为每个新模型定义层时不一定总要从头开始。在一系列相关领域中,有些层是固定的。

模式:KNOWLEDGE LEVEL (知识等级)

KNOWLEDGE LEVEL并不像其他分析模式那样对领域进行建模,而是用来构造模型的。

示例 员工工资和养老金系统,第1部分

这个策略暗示出job  title(工作头衔)字段现在表示了一个重要的领域概念。开发人员可以重构模型,用Employee Type(员工类型)把这个概念明确显示出来。

 

作用:

KNOWLEDGE LEVEL具有两个很有用的特性。

1)首先,它关注的是应用领域,这一点与人们所熟悉的REFLECTION模式的应用正好相反。

2)其次,它并不追求完全的通用性。KNOWLEDGE LEVEL显得更简单,而且可以传达设计者的特别意图。

创建一组不同的对象,用它们来描述和约束基本模型的结构和行为。把这些对象分为两个“级别”,一个是非常具体的级别,另一个级别则提供了一些可供用户或超级用户定制的规则和知识。

示例 员工工资和养老金系统,第2部分:KNOWLEDGE LEVEL

一个Employee Type可以被指定两种Retirement Plan中的任何一种,也可以被指定两种工资中的任何一种。但这实际上并不是用UBIQUITOUS  LANGUAGE中来表达的声明。模型中并没有“payroll”(工资)。他们只是根据自己的需要来讲话,而没有使用实际就有的通用语言。payroll的概念在模型中是隐含的,与Employee Type混在一起。

 

 

 

 

特有的访问约束和一种“事物—事物”型的关系对开发团队起到了提示的作用,使他们看出了隐含的KNOWLEDGE LEVEL。一旦KNOWLEDGE LEVEL被分离出来,它就能够使模型变得非常清晰,从而可以通过提取出Payroll将两个重要的领域概念分开。

模式:PLUGGABLE  COMPONENT FRAMEWORK (可插入式组件框架)

在深入理解和反复精炼基础上得到的成熟模型中,会出现很多机会。通常只有在同一个领域中实现了多个应用程序之后,才有机会使用PLUGGABLE  COMPONENT FRAMEWORK(可插入式组件框架)

PLUGGABLE COMPONENT FRAMEWORK也有几个缺点。一个缺点是它是一种非常难以使用的模式。它需要高精度的接口设计和一个非常深入的模型,以便把一些必要的行为捕获到ABSTRACT CORE中。另一个很大的缺点是它只为应用程序提供了有
限的选择。如果一个应用程序需要对CORE DOMAIN使用一种非常不同的方 法,那么可插入式组件框架将起到妨碍作用。

通过重构得到更合适的结构

控制成本的一个关键是保持一种简单、轻量级的结构。不要试图使结构面面俱到。只需解决最主要的问题即可,其他问题可以留到后面一个一个地解决。开始最好选择一种松散的结构,如SYSTEM  METAPHOR或几个RESPONSIBILITY LAYER。不管怎样,一种最小化的松散结构可以起到轻量级的指导作用,它有助于避免混乱。

整个团队在新的开发和重构中必须遵守结构。要做到这一点,整个团队必须理解这种结构。必须把术语和关系纳入到UBIQUITOUS LANGUAGE中。

对模型施加的另一项关键工作是持续精炼。这可以从各个方面减小修改结构的难度。

总结

本章,重点阐述了大型结构系统中可能存在的一些真实问题,并分别给出了几个指导原则进行加以改进。

模式:EVOLVING ORDER (有序演化):大型系统中的一些复杂规则和约束,在初期不要限制的太严格,因为随着需求的不断变化,这些严格的规则和约束往往会限制住开发人员的手脚,在初期可以稍微宽松点,对规则和约束逐步演进。

模式:SYSTEM METAPHOR (系统隐喻):有利于理解大型系统中的一些构件,需要把隐喻加到通用领域语言内。

模式:RESPONSIBILITY LAYER (按照职责分层):对于复杂系统,需要能通过职责划分出不同的层。分层的艺术可以重点看下示例。

模式:KNOWLEDGE LEVEL (知识等级):用来描述另一组对象该有哪些行为,主要作用用来构造对象。构造的艺术需要重点消化下文中的示例。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值