注:在DDD欧洲大会上,欧洲的ThoughtWorks同事发布了一本电子书《Domain-Driven Design, the first 15years》 这本书集合了在过去15年中DDD社区有影响力的文章。本文翻译自其第11章,转载自 DDD China知乎:https://www.zhihu.com/people/ddd-china
作者:Alexey Zimarev 译者:王柏元 校审:徐培、钟敬
1. 引言
本文是《Hands-On Domain-Driven Design with .NET》一书的第一章
软件行业诞生于20世纪60年代早期,自那时起就日益增长。我们经常会听到这样的预言:总有一天所有的软件都会被开发出来,到那时我们便不再需要更多的软件开发人员。但这个预言从未应验。事实上,为了满足不断增长的用户需求,软件工程师的队伍日益壮大。
然而,从软件行业的早期开始,绝大多数的软件项目,不是远超预算,就是交付延期,甚至以失败告终。根据Standish Group的2015年CHAOS报告统计,从2011年到2015年,IT项目的成功率仅停留在22%的水平,失败率超过了19%,其余的项目也是历经坎坷。这些数字令人惊讶。四十多年以来,尽管许多软件项目管理方法被开发出来,并作为“银弹”加以宣传,但成功项目的数量依旧寥寥。
衡量一个IT项目成功的关键因素,是要理解所设计的系统要解决的问题。
我们已经司空见惯了那些声称能解决问题、但其实是无效或低效的系统。理解要解决的问题,也是精益创业方法的核心原则(由Eric Ries在Crown Publishing公司所出版的“The Lean Startup”一书中提出)。Scrum和XP软件开发方法,都推崇与用户进行沟通,并理解他们的问题。
Eric Evans 在其标志性的著作《领域驱动设计:软件核心复杂性应对之道》(Addison-Wesley公司2004年出版)中,创造了领域驱动设计(DDD)这个术语。该书出版十多年后,人们对于书中所描述的实践和原则的兴趣与日倍增。有很多原因让它广受欢迎,但其中最重要的是,DDD介绍了软件从业人员怎样建立对用户需求的理解,并创造能够解决问题且高效的软件系统。
2. 理解问题
很少有人把软件编写得能触达问题的核心。当然,我们可以仅仅为了好玩或学习新技术,来写一个宠物项目[1]。但对于专业人士,构建软件的目的是帮助他人 “更好、更快、更高效” 地完成工作。不然的话,开发软件是没有意义的。所以,这意味着首先需要有一个打算去解决的“问题”。而问题在认知心理学中的定义,是当前状态和期望状态之间的障碍。
2.1. 问题空间与解空间
在 Human Problem Solving(1972,Englewood Cliffs,N.J:Prentice-Hall)一书中,Allen Newell 和 Herbert Simon 这两位作者对问题空间理论进行了概述。该理论指出,人类是通过在 问题空间(problem space)中寻找解决方案来解决问题的。问题空间描述了问题的初始状态和期望状态,以及可能出现的中间状态,它还可以包含一些定义问题背景的特定约束和规则。在软件行业中,活跃在问题空间中的角色,通常是客户和用户。
每个现实中的问题我们都希望能找到一个解决方案。只要经过在问题空间中充分的探究,我们就可以大致探索出从初始状态达到期望结果之间所需采取的步骤。这些大概的步骤和关于解决方案的所有细节就形成了一个解空间(solution space)。
关于在实施过程中将问题空间与解空间彻底分离,有一个非常经典的案例——一个在太空中写字的故事。在20世纪60年代,人们发现由于缺乏重力,平常使用的圆珠笔在太空中无法使用。于是NASA开发了一支能在太空中写字的圆珠笔,造价高达100万美元;而苏联则用了一些还能用的旧铅笔,就顺利地解决了这一问题,几乎不花费任何成本。
这个故事听起来如此可信以至于它流传至今,甚至还在电视剧《白宫风云》中被马丁·辛扮演的总统所引用。这不仅是因为我们已经对一些受政府资助的机构浪费资金的现象习以为常,更大程度是因为我们曾看到过许多这样的例子:某某某因为效率低下,或者对现实情况的误解,为了去解决一些本来并不存在的问题,而给本来的问题增加了许多不必要的复杂性。
实际上这个故事是虚构的,NASA也曾经尝试过使用铅笔来解决这一问题,但最后由于铅笔会产生微尘、碎屑,以及考虑到木质铅笔的易燃性(不适合在微重力、封闭的飞船中使用),从而放弃了该方案。一家名叫“Fisher Pen”的私营公司利用投资,开发出一款现在我们所知的“太空笔”,NASA测试后决定采用,后来它也获得了苏联的订单而销往海外。而且,它价格公平公道,每支仅仅需要2.39美元。
来源: “事实还是虚构?: NASA花费百万美金开发能在太空上书写的笔,苏联却使用铅笔” by Ciara Curtin, Scientific American
在这个故事中,可以发现关于问题空间和解空间的另一关键:有时候问题本身看起来很简单,但是如果附带一些约束条件,我们可以称为 非功能性需求,就会比初见时复杂得多。
我们的思维直接跳到解决方案有时很简单,我们每个人对于解决日常问题都经验丰富,所以我们都善于迅速找到许多问题的解决方案。但是,Bart Barthelemy和Candace Dalmagne-Rouge在When You’re Innovating, Resist Looking for Solutions (2013, Harvard Business Review)这篇文章中告诉我们,直接思考相关的解决方案会让我们的大脑不去思考本来的问题是什么。相反,我们的大脑容易对第一次浮现出的解决方案先入为主。我们思考问题应该得深入再深入,关注更多方面的细节,让它成为解决某一特定问题的趋于理想的方案。
还有一个要考虑的点是在寻找特定问题的解决方案时,会有一个把所有注意力都聚焦在一个解决方案上的思维陷阱。它可能不是最佳方案的,但是,是你基于以往的经验和当前对问题和其它因素的理解,在脑子里第一个蹦出来的。
“细化”方式和“探索”方式
这种寻找和选择方案的“探索”方式,会让我们花费更多的精力在探索多种可选方案上,但是通过这种方式得到的答案往往会更精确、更有价值。我们将在本章后面更深入地讨论第一种可行方案。
2.2. 需求出了什么问题
我们很多人熟稔软件需求理论。开发人员很少能与想解决问题的人有直接的沟通。通常情况下,我们会有一个像需求分析师、业务分析师或者产品经理之类的专职人员,与客户进行沟通对话,然后以功能需求的形式来进行归纳。
软件需求的形式不一而足,可以从大型的软件需求规范说明书到更“敏捷”的方式比如用户故事。让我们看看下面的例子:
一个系统可以生成每天、每个酒店将会入住和退房的客人列表。
你会发现上面这句话仅仅描述了解决方案。我们不可能知道系统的用户在做什么以及系统所要解决的问题是什么。可能还会定义更多的需求以完善该方案,但是对问题的描述却一直没有出现在功能需求中。
相反,用户故事能让我们更深入地了解用户到底想要什么。比如这个用户故事:“作为一个仓库管理员,我需要能打印库存报告,以便在缺货时可以订货”。但是,这个用户故事已经指定了开发应该做什么,它是在描述解决方案 。而实际的问题可能是用户希望有一个更高效的采购流程,让他们从不缺货。也可能是他们需要一个先进的采购预测系统,以便他们能提高仓库的吞吐量而不堆积库存。
软件需求可谓“臭名昭著”,以至于你在Google图片搜索“软件需求”时,第二条记录会是这张图片:
软件需求并非毫无价值,有很多优秀的分析师可以制定了高质量的需求规范。但是我们需明白:软件需求几乎总是代表写这些需求的人对实际问题的理解。需要花费更多的时间和金钱来写出更高质量需求,这一错误观念在业界颇为盛行。
然而,精益和敏捷方法论越来越鼓励开发人员和用户之间的沟通。了解问题,贯穿于软件构建整个过程中的涉及每一个角色,从终端用户,到开发和测试人员,他们在一起寻找解决方案,消除臆测、构建原型最后让用户评估 —— 这些实践正在被许多成功的团队采用,在本书中你会看到他们和领域驱动设计也息息相关。
-- 未完待续,下接《你在构建正确的软件吗?- 如何处理复杂度》