DDD领域驱动设计---入门书籍:第四部分:战略设计

第四部分:战略设计

当我们无法通过分析对象来理解系统的时候,就需要掌握一些操纵和理解大模型的技术了。

战略设计原则必须把模型的重点放在捕获系统的概念核心,也就是系统的“远景”上。而且在完成这些目标的同时又不能为项目带来麻烦。

整体领域模型需要突出系统中最有价值和最特殊的那些方面,而且在构造领域模型时应该尽可能把注意力集中在这些部分上。

上下文:无论大小,成功的模型必须在逻辑上一致,不能有互相矛盾或重叠的定义。

精炼:精炼可以减少混乱,并且把注意力集中到正确的地方。

大型结构:大型结构是用来描述整个系统的。


第十四章 保持模型的完整性

模型最基本的要求是它应该保持内部一致,术语总具有相同的意义,并且不包含互相矛盾的规则:虽然我们很少明确地考虑这些要求。模型的内部一致性又叫做统一(unification),这种情况下,每个术语都不会有模棱两可的意义,也不会有规则冲突。除非模型在逻辑上是一致的,否则它就没有意义。

BOUNDED CONTEXT(限界上下文)定义了每个模型的应用范围,而CONTEXT MAP(上
下文图)则给出了项目上下文以及它们之间关系的总体视图。这些降低模糊性的技术能够使项目更好地进行,但仅仅有它们还是不够的。一旦确立了CONTEXT的边界之后,仍需要持续集成这种过程,它能够使模型保持统一。

模式:BOUNDED CONTEXT

任何大型项目都会存在多个模型。而当基于不同模型的代码被组合到一起后,软件就会出现bug、变得不可靠和难以理解。团队成员之间的沟通变得混乱。人们往往弄不清楚一个模型不应该在哪个上下文中使用。

明确地定义模型所应用的上下文。根据团队的组织、软件系统的各个部分的用法以及物理表现(代码和数据库模式等)来设臵模型的边界。在这些边界中严格保持模型的一致性,而不要受到边界之外问题的干扰和混淆。

BOUNDED CONTEXT 不是MODULE它们是具有不同动机的不同模式。

识别BOUNDED CONTEXT中的不一致

最明显的是已编码的接口不匹配。对于更微妙的情况,一些意外行为也可能是一种信号。采用了自动测试的CONTINUOUS INTEGRATION可以帮助捕捉到这类问题。但语言上的混乱往往是一种早期的警告信号。

不同模型的元素组合到一起可能会引发两类问题:

重复的概念和假同源。

重复的概念是指两个模型元素(以及伴随的实现)实际上表示同一个概念。每当这个概念的信息发生变化时,都必须更新两个地方。

假同源可能稍微少见一点,但它潜在的危害更大。它是指使用相同术语(或已实现的对象)的两个人认为他们是在谈论同一件事情,但实际上并不是这样。

当发现这些问题时,团队必须要做出相应的决定。可能需要将模型重新整合为一体,并加强用来预防模型分裂的过程。

模式:CONTINUOUS INTEGRATION

最纯粹的XP非常适合维护单一BOUNDED CONTEXT中的模型完整性。但是,无论是否使用XP,都很有必要采取CONTINUOUS INTEGRATION过程。

CONTINUOUS INTEGRATION是指把一个上下文中的所有工作足够频繁地合并到一起,并使它们保持一致,以便当模型发生分裂时,可以迅速发现并纠正问题。像领域驱动设计中的其他方法一样,CONTINUOUS INTEGRATION也有两个级别的操作:

(1) 模型概念的集成; 在讨论模型和应用程序时要坚持使用UBIQUITOUS LANGUAGE。

(2) 实现的集成。

建立一个把所有代码和其他实现工件频繁地合并到一起的过程,并通过自动化测试来快速查明模型的分裂问题。严格坚持使用UBIQUITOUS LANGUAGE,以便在不同人的头脑中演变出不同的概念时,使所有人对模型都能达成一个共识。

模式:CONTEXT MAP

识别在项目中起作用的每个模型,并定义其BOUNDED CONTEXT。这包括非面向对象子系统的隐含模型。为每个BOUNDED CONTEXT命名,并把名称添加到UBIQUITOUS LANGUAGE中。

描述模型之间的联系点,明确所有通信需要的转换,并突出任何共享的内容。

先将当前的情况描绘出来。以后再做改变。

如果团队需要为不同的用户群提供服务,或者团队的协调能力有限,可能就需要采用SHARED KERNEL(共享内核)或CUSTOMER/SUPPLIER(客户/供应商)关系。有时仔细研究需求之后可能发现集成并不重要,而系统最好采用SEPARATE WAY(各行其道)模式。当然,大多数项目都需要与遗留系统或外部系统进行一定程度的集成,这就需要使用OPEN HOST SERVICE(开放主机服务)或ANTICORRUPTION LAYER(防护层)。

模式:SHARED KERNEL

从领域模型中选出两个团队都同意共享的一个子集。当然,除了这个模型子集以外,还包括与该模型部分相关的代码子集,或数据库设计的子集。这部分明确共享的内容具有特殊的地位,一个团队在没与另一个团队商量的情况下不应擅自更改它。

功能系统要经常进行集成,但集成的频率应该比团队中CONTINUOUS INTEGRATION的频率低一些。在进行这些集成的时候,两个团队都要运行测试。

模式:CUSTOMER/SUPPLIER DEVELOPMENT TEAM

一个子系统主要服务于另一个子系统;“下游”组件执行分析或其他功能,这些功能向“上游”组件反馈的信息非常少,所有依赖都是单向的。

上游和下游子系统很自然地分隔到两个BOUNDED CONTEXT中。如果两个组件需要不同的技能或者不同的工具集来实现时,更需要把它们隔离到不同的上下文中。

两个关键要素:

(1) 关系必须是客户与供应商的关系,其中客户的需求是至关重要的。

(2) 必须有自动测试套件,使上游团队在修改代码时不必担心破坏下游团队的工作,并使下游团队能够专注于自己的工作,而不用总是密切关注上游团队的行动。

模式:CONFORMIST

当使用一个具有很大接口的现成组件时,一般应该遵循(CONFORM)该组件中隐含的模型。组件和你自己的应用程序显然是不同的BOUNDED CONTEXT,因此根据团队组织和控制的不同,可能需要使用适配器来进行一点点格式转换,但模型一定要保持相同。

模式:ANTICORRUPTION LAYER

当正在构建的新系统与另一个系统的接口很大时,为了克服连接两个模型而带来的困难,新模型所表达的意图可能会被完全改变,最终导致它被修改得像是另一个系统的模型了(以一种特定的风格)。遗留系统的模型通常很弱。即使对于那些模型开发得很好的例外情况,它们可能也不符合当前项目的需要。然而,集成遗留系统仍然具有很大的价值,而且有时还是绝对必要的。

创建一个隔离层,以便根据客户自己的领域模型来为客户提供相关功能。这个层通过另一个系统现有接口与其进行对话,而只需对那个系统作出很少的修改,甚至无需修改。在内部,这个层在两个模型之间进行必要的双向转换。

ANTICORRUPTION LAYER 本 身 就 可 能 是 一 个 复 杂 的 软 件 。 接 下 来 将 概 要 描 述 在 创 建ANTICORRUPTION LAYER时需要考虑的一些事项。

ANTICORRUPTION LAYER的公共接口通常以一组SERVICE的形式出现,但偶尔也会采用ENTITY的形式。

对ANTICORRUPTION LAYER设计进行组织的一种方法是把它实现为FACADE ADAPTER(这两种模式来自)和转换器的组合,外加两个系统之间进行对话所需的通信和传输机制。

FACADE并不改变底层系统的模型。它应该严格按照另一个系统的模型来编写。否则会产生严重的后果:轻则导致转换职责蔓延到多个对象中,并加重FACADE的负担;重则创建出另一个模型,这个模型既不属于另一个系统,也不属于你自己的BOUNDED CONTEXT。FACADE应该属于另一个系统的BOUNDED CONTEXT,它只是为了满足你的专门需要而呈现出的一个更友好的外观。

ADAPTER是一个包装器,它允许客户使用另外一种协议,这种协议可以是行为实现者不理解的协议。当客户向适配器发送一条消息时,ADAPTER把消息转换为一条在语义上等同的消息,并将其发送给“被适配者”(adaptee)。之后ADAPTER对响应消息进行转换,并将其发回。

概念对象或数据的实际转换是一种完全不同的复杂任务,我们可以让一个单独的对象来承担这项任务,这样可以使负责转换的对象和ADAPTER都更易于理解。转换器可以是一个轻量级的对象,它可以在需要的时候被实例化。

模式:SEPARATE WAY

我们必须严格划定需求的范围。如果两组功能之间的关系并非必不可少,那么二者完全可以彼此独立。

采用SEPARATE WAY(各行其道)模式需要预先决定一些选项。尽管持续重构最后可以撤销任何决策,但完全隔离开发的模型是很难合并的。如果最终仍然需要集成,那么转换层将是必要的,而且可能很复杂。

模式:OPEN HOST SERVICE

定义一个协议,把你的子系统作为一组SERVICE供其他系统访问。开放这个协议,以便所有需要与你的子系统集成的人都可以使用它。当有新的集成需求时,就增强并扩展这个协议,但个别团队的特殊需求除外。满足这种特殊需求的方法是使用一次性的转换器来扩充协议,以便使共享协议简单且内聚。

其他子系统就变成了与OPEN HOST(开放主机)的模型相连接,而其他团队则必须学习HOST团队所使用的专用术语。

模式:PUBLISHED LANGUAGE

把一个良好文档化的、能够表达出所需领域信息的共享语言作为公共的通信媒介,必要时在其他信息与该语言之间进行转换。

承认多个互相冲突的领域模型实际上正是面对现实的做法。通过明确定义每个模型都适用的上下文,可以维护每个模型的完整性,并清楚地看到要在两个模型之间创建的任何特殊接口的含义。

**选择模型上下文策略 **

  • 团队决策或更高层决策
  • 置身上下文中
  • 转换边界
  • 接受那些我们无法更改的事物:描述外部系统
  • 与外部系统的关系
  • 设计中的系统
  • 用不同的模型满足特殊需求
  • 部署
  • 权衡

转换

  • 合并CONTEXT:SEPARATE WAY →SHARED KERNEL
  • 合并CONTEXT:SHARED KERNEL→CONTINUOUS INTEGRATION
  • 逐步淘汰遗留系统
  • OPEN HOST SERVICE→PUBLISHED LANGUAGE

第十五章 精炼

精炼是把一堆混杂在一起的组件分开的过程,以便通过某种形式从中提取出最重要的内容,而这种形式将使它更有价值,也更有用。模型就是知识的精炼。通过每次重构所得到的更深层的理解,我们得以把关键的领域知识和优先级提取出来。

领域模型的战略精炼包括以下部分:

(1) 帮助所有团队成员掌握系统的总体设计以及各部分如何协调工作;

(2) 找到一个具有适度规模的核心模型并把它添加到通用语言中,从而促进沟通;

(3) 指导重构;

(4) 专注于模型中最有价值的那部分;

(5) 指导外包、现成组件的使用以及任务委派。

模式:CORE DOMAIN

一个严峻的现实是我们不可能对所有设计部分进行同等的精化,而是必须分出优先级。为了使领域模型成为有价值的资产,必须整齐地梳理出模型的真正核心,并完全根据这个核心来创建应用程序的功能。但本来就稀缺的高水平开发人员往往会把工作重点放在技术基础设施上,或者只是去解决那些不需要专门领域知识就能理解的领域问题(这些问题都已经有了很好的定义)。

对模型进行提炼。找到CORE DOMAIN并提供一种易于区分的方法把它与那些起辅助作用的模型和代码分开。最有价值和最专业的概念要轮廓分明。尽量压缩CORE DOMAIN。

让最有才能的人来开发CORE DOMAIN,并据此要求进行相应的招聘。在CORE DOMAIN中努力开发能够确保实现系统蓝图的深层模型和柔性设计。仔细判断任何其他部分的投入,看它是否能够支持这个提炼出来的CORE。

对CORE DOMAIN的选择取决于看问题的角度。一个应用程序的CORE DOMAIN在另一个应用程序中可能只是通用的支持组件。

建立一支由开发人员和一位或多位领域专家组成的联合团队,其中开发人员必须能力很强、能够长期稳定地工作并且对学习领域知识非常感兴趣,而领域专家则要掌握深厚的业务知识。

一份简单的DOMAIN VISION STATEMENT(领域愿景说明)只需很少的投入,它传达了基本概念以及它们的价值。

HIGHLIGHTED CORE(突出核心)可以增进沟通,并指导决策制定,这也只需对设计进行很少的改动甚至无需改动。

更积极的精炼方法是通过重构和重新打包显式地分离出GENERIC SUBDOMAIN,然后单独进行处理。在使用COHESIVE MECHANISM的同时,也要保持设计的通用性、易懂性和柔性,这两个方面可以结合起来。只有除去了这些细枝末节,才能把CORE剥离出来。

重新打包出一个SEGREGATED CORE(分离的核心),可以使这个CORE清晰可见(即使在代码中也是如此),并且促进将来在CORE模型上的工作。

最富雄心的精炼是ABSTRACT CORE(抽象内核),它用纯粹的形式表示了最基本的概念和关系(因此,需要对模型进行全面的重新组织和重构)。

模式:GENERIC SUBDOMAIN

模型中有些部分除了增加复杂性以外并没有捕捉或传递任何专门的知识。任何外来因素都会使CORE DOMAIN愈发的难以分辨和理解。模型中充斥着大量众所周知的一般原则,或者是专门的细节,这些细节并不是我们的主要关注点,而只是起到支持作用。然而,无论它们是多么通用的元素,它们对实现系统功能和充分表达模型都是极为重要的。

识别出那些与项目意图无关的内聚子领域。把这些子领域的通用模型提取出来,并放到单独的MODULE中。任何专有的东西都不应放在这些模块中。把它们分离出来以后,在继续开发的过程中,它们的优先级应低于CORE DOMAIN的优先级,并且不要分派核心开发人员来完成这些任务(因为他们很少能够从这些任务中获得领域知识)。此外,还可以考虑为这些GENERIC SUBDOMAIN使用现成的解决方案或“公开发布的模型”(PUBLISHED MODEL)。

选择1:现成的解决方案

选择2:公开发布的设计或模型

选择3:把实现外包出去

选择4:内部实现

模式:DOMAIN VISION STATEMENT

在项目开始时,模型通常并不存在,但是模型开发的需求是早就确定下来的重点。在后面的开发阶段,我们需要解释清楚系统的价值,但这并不需要深入地分析模型。此外,领域模型的关键方面可能跨越多个BOUNDED CONTEXT,而且从定义上看,无法将这些彼此不同的模型组织起来表明其共同的关注点。

写一份CORE DOMAIN的简短描述(大约一页纸)以及它将会创造的价值,也就是“价值主张”。那些不能将你的领域模型与其他领域模型区分开的方面就不要写了。展示出领域模型是如何实现和均衡各方利益的。这份描述要尽量精简。尽早把它写出来,随着新的理解随时修改它。

模式:HIGHLIGHTED CORE

尽管团队成员可能大体上知道核心领域是由什么构成的,但CORE DOMAIN中到底包含哪些元素,不同的人会有不同的理解,甚至同一个人在不同的时间也会有不同的理解。如果我们总是要不断过滤模型以便识别出关键部分,那么就会分散本应该投入到设计上的精力,而且这还需要广泛的模型知识。因此,CORE DOMAIN必须要很容易被分辨出来。

对代码所做的重大结构性改动是识别CORE DOMAIN的理想方式,但这些改动往往无法在短期内完成。事实上,如果团队的认识还不够全面,这样的重大代码修改是很难进行的。

精炼文档并不是完备的设计文档。它只是一个最简单的切入点,描述并解释了核心,并给出了更进一步研究这些核心部分的理由。

编写一个非常简短的文档(3~7页,每页内容不必太多),用于描述CORE DOMAIN以及CORE元素之间的主要交互过程。

把模型的主要存储库中的CORE DOMAIN标记出来,不用特意去阐明其角色。使开发人员很容易就知道什么在核心内,什么在核心外。

如果精炼文档概括了CORE DOMAIN的核心元素,那么它就可以作为一个指示器——用以指示模型改变的重要程度。当模型或代码的修改影响到精炼文档时,需要与团队其他成员一起协商。当对精炼文档做出修改时,需要立即通知所有团队成员,而且要把新版本的文档分发给他们。CORE外部的修改或精炼文档外部的细节修改则无需协商或通知,可以直接把它们集成到系统中,其他成员在后续工作过程中自然会看到这些修改。这样开发人员就拥有了XP所建议的完全的自治性。

模式:COHESIVE MECHANISM

把复杂算法隐藏到方法中,再为方法起一个一看就知道其用途的名字,这样就把“做什么”和“如何做”分开了。

把概念上的COHESIVE MECHANISM(内聚机制)分离到一个单独的轻量级框架中。要特别注意公式或那些有完备文档的算法。用一个INTENTION-REVEALING INTERFACE来暴露这个框架的功能。现在,领域中的其他元素就可以只专注于如何表达问题(做什么)了,而把解决方案的复杂细节(如何做)转移给了框架。

模型提出问题,COHESIVE MECHANISM解决问题。

把GENERIC SUBDOMAIN提取出来可以减少混乱,而COHESIVE MECHANISM可以把复杂操作封装起来。这样可以得到一个更专注的模型,从而减少了那些对用户活动没什么价值的、分散注意力的方面。

模式:SEGREGATED CORE

模型中的元素可能有一部分属于CORE DOMAIN,而另一部分起支持作用。核心元素可能与一般元素紧密耦合在一起。CORE的概念内聚性可能不是很强,看上去也不明显。这种混乱性和耦合关系抑制了CORE。设计人员如果无法清晰地看到最重要的关系,就会开发出脆弱的设计。

对模型进行重构,把核心概念从支持性元素(包括定义得不清楚的那些元素)中分离出来,并增强CORE的内聚性,同时减少它与其他代码的耦合。把所有通用元素或支持性元素提取到其他对象中,并把这些对象放到其他的包中——即使这会把一些紧密耦合的元素分开。

通过重构得到SEGREGATED CORE的一般步骤如下所示:

(1) 识别出一个CORE子领域(可能是从精炼文档中得到的)。

(2) 把相关的类移到新的MODULE中,并根据与这些类有关的概念为模块命名。

(3) 对代码进行重构,把那些不直接表示概念的数据和功能分离出来。把分离出来的元素放到其他包的类(可以是新的类)中。尽量把它们与概念上相关的任务放在一起,但不要为了追求完美而浪费太长时间。把注意力放在提炼CORE子领域上,并且使CORE子领域对其他包的引用变得更明显且易于理解。

(4) 对新的SEGREGATED CORE MODULE进行重构,使其中的关系和交互变得更简单、表达得更清楚,并且最大限度地减少并澄清它与其他MODULE的关系(这将是一个持续进行的重构目标)。

(5) 对另一个CORE子领域重复这个过程,直到完成SEGREGATED CORE的工作。

模式:ABSTRACT CORE

当不同MODULE的子领域之间有大量交互时,要么需要在MODULE之间创建很多引用,这在很大程度上抵消了划分模块的价值;要么就必须间接地实现这些交互,而后者会使模型变得晦涩难懂。

把模型中最基本的概念识别出来,并分离到不同的类、抽象类或接口中。设计这个抽象模型,使之能够表达出重要组件之间的大部分交互。把这个完整的抽象模型放到它自己的MODULE中,而专用的、详细的实现类则留在由子领域定义的MODULE中。

尽管任何带来深层模型的突破都有价值,但只有CORE DOMAIN中的突破才能改变整个项目的轨道。


第十六章 大型结构

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

设计一种应用于整个系统的规则(或角色和关系)模式,使人们可以通过它在一定程度上了解各个部分在整体中所处的位臵(即使是在不知道各个部分的详细职责的情况下)。

模式:EVOLVING ORDER

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

让这种概念上的大型结构随着应用程序一起演变,甚至可以变成一种完全不同的结构风格。不要依此过分限制详细的设计和模型决策,这些决策和模型决策必须在掌握了详细知识之后才能确定。

当发现一种大型结构可以明显使系统变得更清晰,而又没有对模型开发施加一些不自然的约束时,就应该采用这种结构。使用不合适的结构还不如不使用它,因此最好不要为了追求设计的完整性而勉强去使用一种结构,而应该找到尽可能精简的方式解决所出现问题。要记住宁缺勿滥的原则。

模式:SYSTEM METAPHOR

软件设计往往非常抽象且难于掌握。开发人员和用户都需要一些切实可行的方式来理解系统,并共享系统的一个整体视图。

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

当系统的一个具体类比正好符合团队成员对系统的想象,并且能够引导他们向着一个有用的方向进行思考时,就应该把这个类比用作一种大型结构。围绕这个隐喻来组织设计,并把它吸收到UBIQUITOUS LANGUAGE中。SYSTEM METAPHOR应该既能促进系统的交流,又能指导系统的开发。它可以增加系统不同部分之间的一致性,甚至可以跨越不同的BOUNDED CONTEXT。但所有隐喻都不是完全精确的,因此应不断检查隐喻是否过度或不恰当,当发现它起到妨碍作用时,要随时准备放弃它。

模式:RESPONSIBILITY LAYER

如果每个对象的职责都是人为分配的,将没有统一的指导原则和一致性,也无法把领域作为一个整体来处理。为了保持大模型的一致,有必要在职责分配上实施一定的结构化控制。

注意观察模型中的概念依赖性,以及领域中不同部分的变化频率和变化的原因。如果在领域中发现了自然的层次结构,就把它们转换为宽泛的抽象职责。这些职责应该描述系统的高层目的和设计。对模型进行重构,使得每个领域对象、AGGREGATE和MODULE的职责都清晰地位于一个职责层当中。

模式:KNOWLEDGE LEVEL

“KNOWLEDGE LEVEL是”一组描述了另一组对象应该有哪些行为的对象。

如果在一个应用程序中,ENTITY的角色和它们之间的关系在不同的情况下有很大变化,那么复杂性会显著增加。在这种情况下,无论是一般的模型还是高度定制的模型,都无法满足用户的需求。为了兼顾各种不同的情形,对象需要引用其他的类型,或者需要具备一些在不同情况下包括不同使用方式的属性。具有相同数据和行为的类可能会大量增加,而这些类的唯一作用只是为了满足不同的组装规则。

KNOWLEDGE LEVEL是REFLECTION(反射)模式在领域层中的一种应用,很多软件架构和技术基础设施中都使用了它。REFLECTION模式能够使软件具有自我感知的特性,并使所选中的结构和行为可以接受调整和修改,从而满足变化需要。

模式:PLUGGABLE COMPONENT FRAMEWORK

当很多应用程序需要进行互操作时,如果所有应用程序都基于相同的一些抽象,但它们是独立设计的,那么在多个BOUNDED CONTEXT之间的转换会限制它们的集成。各个团队之间如果不能紧密地协作,就无法形成一个SHARED KERNEL。重复和分裂将会增加开发和安装的成本,而且互操作会变得很难实现。

从接口和交互中提炼出一个ABSTRACT CORE,并创建一个框架,这个框架要允许这些接口的各种不同实现被自由替换。同样,无论是什么应用程序,只要它严格地通过ABSTRACT CORE的接口进行操作,那么就可以允许它使用这些组件。


第十七章 领域驱动设计的综合运用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A8r5QTM5-1621160415877)(G:\研究方向\DDD领域驱动设计\photo\DDD入门书籍\image-20210516180018559.png)]

对一个项目进行战略设计时,首先需要清晰地评估现状。

(1) 画出CONTEXT MAP。你能画出一个一致的图吗?有没有一些模棱两可的情况?

(2) 注意项目上的语言使用。有没有UBIQUITOUS LANGUAGE?这种语言是否足够丰富,以便帮助开发?

(3) 理解重点所在。CORE DOMAIN被识别出来了吗?有没有DOMAIN VISION STATEMENT?你能写一个吗?

(4) 项目所采用的技术是遵循MODEL-DRIVEN DESIGN,还是与之相悖?

(5) 团队开发人员是否具备必要的技能?

(6) 开发人员是否了解领域知识?他们对领域是否感兴趣?

制定战略设计决策的6个要点

  1. 决策必须传达到整个团队
  2. 决策过程必须收集反馈意见
  3. 计划必须允许演变
  4. 架构团队不必把所有最好、最聪明的人员都吸收进来
  5. 战略设计需要遵守简约和谦逊的原则
  6. 对象的职责要专一,而开发人员应该是多面手

很容易通过几个方面辨认出一个项目是否采用了领域驱动设计。标志性的特征是把“理解目标领域并将学到的知识融合到软件中”当作首要任务。

其他工作都以它为前提。团队成员在项目中有意识地使用通用语言,并且不断对语言进行精化。

由于他们不断地学习越来越多的领域知识,因此他们永远不会满足于现有领域模型的质量。他们把持续精化视作机会,把不适当的模型视作风险。他们知道,开发出高质量的、能够清晰反映出领域模型的软件并非易事,因此他们一丝不苟地运用设计技巧。他们也因为遇到障碍而跌倒过,但却始终坚持自己的原则,百折不挠,继续前进。

创建好的软件是一项需要学习和思考的活动。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值