非原创,感谢《领域驱动设计》这本书数据库
领域模型可成为软件项目通用语言的核心。该模型是一组得自于项目人员头脑中的概念,以及反映了领域深层含义的术语和关系。这些术语和相互关系提供了模型语言的语义,虽然语言是为领域量身定制的,但就技术开发而言,其依然足够精确。正是这条相当重要的纽带,将模型与开发活动结合在一块儿,并使模型与代码紧密绑定。这种基于模型的交流并不局限于UML(统一建模语言)图。为了最有效地使用模型,须要充分利用各类交流手段。基于模型的交流提升了书面文档的效用,也提升了敏捷过程当中再度强调的非正式图表和交谈的效用。它还经过代码自己及对应的测试促进了交流。编程
虽然领域专家对软件开发的技术术语所知有限,但他们能熟练使用本身领域的术语——可能还具备各类不一样的风格。另外一方面,开发人员可能会用一些描述性的、功能性的术语来理解和讨论系统,而这些术语并不具有领域专家的语言所要传达的意思。或者,开发人员可能会建立一些用于支持设计的抽象,但领域专家没法理解这些抽象。负责处理问题不一样部分的开发人员可能会开发出各自不一样的设计概念以及描述领域的方式.编程语言
因为语言上存在鸿沟,领域专家们只能模糊地描述他们想要的东西。开发人员虽然努力去理解一个本身不熟悉的领域,但也只能造成模糊的认识。虽然少数团队成员会设法掌握这两种语言,但他们会变成信息流的瓶颈,而且他们的翻译也不许确。(沟通很是重要)工具
在一个没有公共语言的项目上,开发人员不得不为领域专家作翻译。而领域专家须要充当开发人员与其余领域专家之间的翻译。甚至开发人员之间还须要互相翻译。这些翻译使模型概念变得混淆,而这会致使有害的代码重构。这种间接的沟通掩盖了分裂的造成——不一样的团队成员使用不一样的术语而尚不自知。因为软件的各个部分不可以浑然一体,所以这就致使没法开发出可靠的软件。翻译工做致使各种促进深刻理解模型的知识和想法没法结合到一块儿。学习
平常讨论所使用的术语与代码(软件项目的最重要产品)中使用的术语不一致。甚至同一我的在讲话和写东西时使用的语言也不一致,这致使的后果是,对领域的深入表述经常稍纵即逝,根本没法记录到代码或文档中。翻译使得沟通不顺畅,并削弱了知识消化。测试
然而任何一方的语言都不能成为公共语言,由于它们没法知足全部的需求。全部翻译的开销,连带着误解的风险,成本实在过高了。项目须要一种公共语言,这种语言要比全部语言的最小公分母健壮得多。经过团队的一致努力,领域模型能够成为这种公共语言的核心,同时将团队沟通与软件实现紧密联系到一块儿。该语言将存在于团队工做中的方方面面。ui
我的理解:上面说法太绝对了,主要是为了突出通用语言的重要性。没必要在乎。编码
UBIQUITOUS LANGUAGE(通用语言)的词汇包括类和主要操做的名称。语言中的术语,有些用来讨论模型中已经明确的规则,还有一些则来自施加于模型上的高级组织原则。最后,团队经常应用于领域模型的模式名称也使这种语言更为丰富。翻译
开发人员应该使用基于模型的语言来描述系统中的工件、任务和功能。这个模型应该为开发人员和领域专家提供一种用于相互交流的语言,并且领域专家还应该使用这种语言来讨论需求、开发计划和特性。语言使用得越广泛,理解进行得就越顺畅。设计
至少,咱们应该将它做为目标。但最初,模型可能不太好,所以没法很好地履行这些职责。它可能不会像领域的专业术语那样具备丰富的语义。但咱们又不能直接使用那些术语,由于它们有歧义和矛盾。模型可能缺少开发人员在代码中所建立的更为微妙和灵活的特性,这要么是由于开发人员认为模型没必要具有这些特性,要么是由于编码风格是过程式的,只能隐含地表达领域概念。
尽管模型和基于模型的语言之间的次序像是循环论证,可是,可以产生更有用模型的知识消化过程依赖于团队投身于基于模型的语言。持续使用UBIQUITOUS LANGUAGE能够暴露模型中存在的缺点,这样团队就能够尝试并替换不恰当的术语或组合。当在语言中发现缺失时,新的词语将被引入到讨论中。这些语言上的更改也会在领域模型中引发相应的更改,并促使团队更新类图并重命名代码中的类和方法,当术语的意义改变时,甚至会致使行为也发生改变。
我的理解:尽管模型难以很快的理解,有可能一个团队用了好久才达成共识造成一套本身理解的模型,可是对于刚刚加入的人来讲就像天书,无疑增长的学习成本,若是模型更新过程当中,有些术语发生变动(随着理解的深刻),会致使功能重作。
将模型做为语言的支柱。确保团队在内部的全部交流中以及代码中坚持使用这种语言。在画图、写东西,特别是讲话时也要使用这种语言。经过尝试不一样的表示方法(它们反映了备选模型)来消除难点。而后重构代码,从新命名类、方法和模块,以便与新模型保持一致。解决交谈中的术语混淆问题,就像咱们对普通词汇造成一致的理解同样。要认识到,UBIQUITOUS LANGUAGE的更改就是对模型的更改。领域专家应该抵制不合适或没法充分表达领域理解的术语或结构,开发人员应该密切关注那些将会妨碍设计的有歧义和不一致的地方。有了UBIQUITOUS LANGUAGE,模型就不只仅是一个设计工件了。它成为开发人员和领域专家共同完成的每项工做中不可或缺的部分。语言以动态形式传递知识。使用这种语言进行讨论可以呈现图和代码背后的真实含义。
假如将交谈从沟通方式中除去的话,那会是巨大的损失,由于人类自己颇具谈话的天赋。遗憾的是,当人们交谈时,一般并不使用领域模型的语言。
可能开始时你并不认为上述论断是正确的,并且的确有例外状况。但下次你参加需求或设计讨论时,不妨认真听一下。你将听到人们用业务术语或者各类业余术语来描述功能。还会听到人们讨论技术工件和具体的功能。固然,你还会听到来自领域模型的术语;在人们共同使用的那部分业务术语中,那些显而易见的名词在编码时一般被用做对象名称,所以这些术语常常被人们说起。但你是否也听到一些使用当前领域模型中的关系和交互来描述的措辞呢?
改善模型的最佳方式之一就是经过对话来研究,试着大声说出可能的模型变化中的各类结构。这样不完善的地方很容易被听出来。
例如:“若是咱们向Routing Service提供出发地、目的地和到达时间,就能够查询货物的停靠地点,嗯……将它们存到数据库中。”(含糊且偏重于技术);“出发地、目的地……把它们都输入到Routing Service中,然后咱们获得一个Itinerary,它包含咱们所需的所有信息。”(更具体,但过于啰嗦);“Routing Service查找知足Route Specification的Itinerary。”(简洁)
我的理解:简洁、抽象、完整的表达,就是模型的描述语言。尽可能不说白话,相似文言文。若是刚开始使用模型语言不习惯,也要在沟通时候去适应,大胆说出来,一块儿适应,造成习惯。
讨论系统时要结合模型。使用模型元素及其交互来大声描述场景,而且按照模型容许的方式将各类概念结合到一块儿。找到更简单的表达方式来说出你要讲的话,而后将这些新的想法应用到图和代码中。
技术人员一般认为业务专家最好不要接触领域模型,他们认为:
“领域模型对他们来讲太抽象了。”
“他们不理解对象。”
“这样咱们就不得不用他们的术语来收集需求。”
固然,设计中有一些技术组件与领域专家无关,但模型的核心最好让他们参与。过于抽象?那你怎么知道抽象是否合理?你是否像他们同样深刻理解领域?有时,某些特定需求是从底层用户那里收集的,他们在描述这些需求时可能会用到一小部分更具体的术语,但领域专家应该可以更深刻地思考他们所从事的领域。若是连经验丰富的领域专家都不能理解模型,那么模型必定出了什么问题。
最初,当用户讨论系统还没有建模的将来功能时,他们没有模型可供使用。但当他们开始与开发人员一块儿仔细讨论这些新想法时,探索共享模型的过程就开始了。最初的模型可能很笨拙且不完整,但会逐渐精化。随着新语言的演进,领域专家必须付出更多努力来适应它,并更新那些仍然很重要的旧文档。当领域专家使用这种语言互相讨论,或者与开发人员进行讨论时,很快就会发现模型中哪些地方不符合他们的须要,甚至是错误的。另外一方面,模型语言的精确性也会促使领域专家(在开发人员的帮助下)发现他们想法中的矛盾和含糊之处。
我的理解:不要担忧业务领域专家听不懂技术设计的模型语言,你们能够一块儿来讨论,共同探索,业务人员也要主动去适应,一旦理解后,能够提出本身的意见,帮助改进模型。总的来讲,使用模型就是好,有困难-克服。
开发人员和领域专家能够经过一步一步地使用模型对象来走查场景,从而对模型进行非正式的测试。每次讨论都是开发人员和专家一块儿使用模型的机会,在这个过程当中,他们能够加深彼此的理解,并对概念进行精化。领域专家可使用模型语言来编写用例,甚至能够直接利用模型来具体说明验收测试。
开发人员的确会使用领域专家没法理解的技术术语。开发人员有其所需的大量术语来讨论系统技术。几乎能够确定的是,用户也会用开发人员没法理解的、超出应用程序范畴的专用术语。这些都是对语言的扩展。但在这些语言扩展中,同一领域的相同词汇不该该反映不一样的模型。有了UBIQUITOUS LANGUAGE以后,开发人员之间的对话、领域专家之间的讨论以及代码自己所表达的内容都基于同一种语言,都来自于一个共享的领域模型。
每当我参加讨论软件设计的会议时,若是不在白板或画板上画图,我就很难讨论下去。我画的大部分是UML图,主要以类图和对象交互图为主。
有些人天生是视觉动物,图能够帮助人们掌握某些类型的信息。UML图在传达对象之间的关系上真是游刃有余,并且也很擅长表现交互。但它们却没法给出这些对象的概念定义。在会议中,我会一边画图一边用语言来丰富它们的意义,或者在与其余参与者讨论时进行解释。简单、非正式的UML图可以维系整个讨论。绘制一幅包含当前问题最关键的3~5个对象的图,这样每一个人均可以集中注意力。全部人就对象关系会达成一致的认识,更重要的是,他们将使用相同的对象名称。如此,口头讨论会更加高效。当人们尝试不一样的想法时,图也随之改变,草图在某种程度上能够反映讨论的变化,这是讨论中真正重要的部分。毕竟,UML就是统一建模语言。
当人们必须经过UML图表示整个模型或设计时,麻烦也随之而来。不少对象模型图在某些方面过于细致,同时在某些方面又有不少遗漏。说它们过于细致是由于人们认为必须将全部要编码的对象都放到建模工具中。而细节过多的结果是“只见树木,不见森林”。
我的理解:我认为uml也能够说是模型的一种表达形式,随便在白板上划也是一种模型,只不过不那么规范,比较随意
UML也不是一种十分使人满意的编程语言。我从未见过有人使用建模工具的代码生成功能达到了预期目的。若是UML的能力没法知足须要,一般人们就不得不忽略模型最关键的部分,由于有些规则并不适合用线框图来表示。固然,代码生成器也没法使用上面所说的那些文本注释。若是确实能使用UML这样的绘图语言来编写可执行程序,那么UML图就会退化为程序自己的另外一种视图,这样,“模型”的真正含义就丢失了。若是使用UML做为实现语言,则仍然须要利用其余手段来表达模型的确切含义。
图是一种沟通和解释手段,它们能够促进头脑风暴。简洁的小图可以很好地实现这些目标,而涵盖整个对象模型的综合性大图反而失去了沟通或解释能力,由于它们将读者淹没在大量细节之中,加之这些图也缺少目的性。鉴于此,咱们应避免使用一应俱全的对象模型图,甚至不能使用包含全部细节的UML数据存储库。相反,应使用简化的图,图中只包含对象模型的重要概念——这些部分对于理解设计相当重要。本书中的图都是我在项目中使用过比较典型的图。它们很简单,并且具备很强的解释能力,在澄清一些要点时,还使用了一些非标准的符号。它们显示了设计约束,但它们不是面面俱到的设计规范。它们只体现了思想纲要。
设计的重要细节应该在代码中体现出来。良好的实现应该是透明的,清楚地展现其背后的模型。互为补充的图和文档可以引导人们将注意力放在核心要点上。天然语言的讨论能够填补含义上的细微差异。这就是为何我喜欢把典型的UML使用方法颠倒过来的缘由。一般的用法是以图为主,辅以文本注释;而我更愿意以文本为主,用精心挑选的简化图做为说明。
模型不是图。图的目的是帮助表达和解释模型。代码能够充当设计细节的存储库。书写良好的Java代码与UML具备一样的表达能力。通过仔细选择和构造的图能够帮助人们集中注意力,并起到指导做用,固然前提条件是不能强制用图来表示所有模型或设计,由于这样会削弱图的清晰表达的能力。
口头交流能够解释代码的含义,所以可做为代码精确性和细节的补充。虽然交谈对于将人们与模型联系起来是相当重要的,但书面文档也是必不可少的,任何规模的团队都须要它来提供稳定和共享的交流。但要想编写出可以帮助团队开发出好软件的书面文档倒是一个不小的挑战。
一句话:好记性不如烂笔头。文档应做为代码和口头交流的补充
每种敏捷过程在编写文档方面都有本身的理念。极限编程主张彻底不使用(多余的)设计文档,而让代码解释本身。实际运行的代码不会说谎,而其余文档则否则。运行代码所产生的行为是明确的。
极限编程就是敏捷开发,敏捷开发不提倡写太多文档,能省就省,代码多些注释,代替文档。
极限编程只关注对程序及可执行测试起做用的因素。因为为代码添加的注释并不影响程序的行为,所以它们每每没法与当前代码及其模型保持同步。外部文档和图也不会影响程序的行为,所以它们也没法保持同步。另外一方面,口头交流和临时在白板上画的图不会长久保留而产生混淆。依赖代码做为交流媒介能够促使开发人员保持代码的整洁和透明。
将代码做为设计文档也有局限性。它可能会把读代码的人淹没在细节中。尽管代码的行为是很是明确的,但这并不意味着其行为是显而易见的。就算技术人员能够看懂代码,专业领域的业务人员怎么办???因此,文档仍是有必要的,实事求是来制定开发方式和文档编写方式。
文档应当鲜活并保持最新。设计文档的最大价值在于解释模型的概念,帮助在代码的细节中指引方向,或许还能够帮助人们深刻了解模型预期的使用风格。根据不一样的团队理念,整个设计文档可能会十分简单,如只是贴在墙上的一组草图,也可能会很是详尽。
良好的代码具备很强的表达能力,但它所传递的信息不能确保是准确的。一段代码所产生的实际行为是不会改变的。可是,方法名称可能会有歧义、会产生误导或者由于已通过时而没法表示方法的本质含义。变量和代码组织方式所表达出来的意思未必严格。好的编程风格会尽力使这种联系直接化,但其仍然主要靠开发人员的自律。编码时须要一丝不苟的态度,只有这样才能编写出“言行所有正确”的代码。
在实现、设计和团队交流中使用同一个模型做为基础。若是各有各的模型,将会形成危害。
模型在帮助领域学习方面也具备很大价值。对设计起到推进做用的模型是领域的一个视图,但为了学习领域,还能够引入其余视图,这些视图只用做传递通常领域知识的教学工具。出于此目的,人们可使用与软件设计无关的其余种类模型的图片或文字。
驱动软件开发过程的技术模型必须通过严格的精简,以便用最小化的模型来实现其功能。而解释性模型则能够包含那些提供上下文的领域方面——这些上下文用于澄清范围更窄的模型。
解释性模型提供了必定的自由度,能够专门为某个特殊主题定制一些表达力更强的风格。领域专家在一个领域中所使用的视觉隐喻一般呈现了更清晰的解释,这能够教给开发人员领域知识,同时使领域专家们的意见更一致。解释性模型还能够以一种不一样的方式来呈现领域,而且各类不一样角度的解释有助于人们更好地学习。
解释性模型没必要是对象模型,并且最好不是。实际上在这些模型中不使用UML是有好处的,这样能够避免人们错误地认为这些模型与软件设计是一致的。尽管解释性模型与驱动设计的模型每每有对应关系,但它们并不彻底相似。为了不混淆,每一个人都必须知道它们之间的区别。
例如:
考虑一个用来追踪航运公司货物的应用程序。模型包含一个详细的视图,它显示了如何将港口装卸和货轮航次组合为一次货运的操做计划:
但对外行而言,类图可能起不到多大的说明做用。
在这种状况下,解释性模型能够帮助团队成员理解类图的实际含义。图2-5是表示相同概念的另外一种方式。
图中的每根线段都表示货物的一种状态——或者正在港口装卸(装货或卸货),或者停放在仓库里,或者正在运输途中。这个图并无与类图中的细节一一对应,但强调了领域的要点。这种图连同对它所表示的模型的天然语言解释,可以帮助开发人员和领域专家理解更严格的软件模型图。综合使用这两种图要比单独使用一种图更容易理解。