业务分析与设计的方法
现在,用户的需求越来越复杂,变化也越来越快,如果仍然通过需求管理、需求跟踪等管理方式来约束和减少频繁变更需求对软件开发带来的冲击,则会导致软件开发流程变得僵硬,程序员更加疲惫。
另外,用户的需求通常来自某个专业领域,比如法律、财务或电子商务等,每个特定的需求又有其特别复杂之处,所以几乎没有人能够第一时间抓住这些专业领域的需求本质。因此,用户的需求在历经几次演变之后变得面目全非,每一个“加工制造环节”都认为自己在做“正确的事”。在现实工作中,这样的局面一再上演,比如,产品经理在宣讲产品需求文档(Product Requirement Document,PRD)时,需要将专业名词使用通俗的业务语言“翻译”给业务人员,还要使用技术语言“翻译”给开发人员,这就很容易导致各方得到的信息不对等,业务人员的理解和技术人员的理解可能不一致。
因此,聪明的工程师们引入了灵活多变的面向对象分析与设计(OOAD)方法。面向对象分析与设计方法对复杂需求的解决方法是:让建模专家进行需求分析,并在需求和需求之间建立关系。
注意:面向对象分析与设计被拆分为系统分析和系统设计两部分,还专门有“系统分析师”和“系统设计师”两种职称考试。这样拆分的结果就是对需求分析的结果无法直接进行设计和编程,而能够运行的代码不匹配需求,导致客户在运行软件后才发现很多功能不是自己想要的,而且软件不能快速跟上需求的变化。
虽然面向对象分析与设计的思想带给分析与设计很大的灵活性,也对软件开发产生了前所未有的影响,但有一定的局限性:面向对象分析与设计主要关注微观层次的抽象,比如类和对象实例等;对每个问题域通常都需要创建单独的用例分析模型,项目或产品的大方向在许多情况下变得很模糊,很难全局把控系统的总目标,所以这样的系统分析与设计方式存在很大的风险。
面向对象分析与设计的局限性,催生了面向服务分析与设计(SOAD)方法,它有效地弥补了面向对象分析与设计的局限性。同时,面向服务的架构(Service-Oriented Architecture,SOA)也走进了大众的视野并很快流行起来。
面向服务分析与设计并不是一种全新的分析与设计方式,只不过是从不同的抽象角度去设计一种业务模型。面向对象分析与设计可以说是一种自底向顶的设计方式,虽然面向对象的方法比起面向过程的方法有了很大的改进,但是在面对复杂的市场需求时,面向对象分析与设计就显得捉襟见肘了,此时就需要从更高的层次分解市场需求,面向服务分析与设计应运而生。在做面向服务分析与设计时会采用自顶向底的设计方法,首先要分离出业务流程和服务,然后细化对象。面向对象分析与设计与面向服务分析与设计的抽象关系如图3.16所示。
图3.16
那么,面向服务分析与设计就是最好的了吗?它又有什么局限性呢?
众所周知,软件开发的流程通常为需求、分析、设计、开发、测试和交付。不管是在面向对象分析与设计中还是在面向服务分析与设计中,对系统分析和设计都是分开的、割裂的,即分析人员从领域中收集基本的业务概念,系统设计人员再将基本的业务概念映射为相应的编程工具的构造组件。在这个过程中,由于分析模型和设计模型不同,在分析和设计之间形成一条鸿沟,如图3.17所示。
图3.17
2004 年,著名建模专家 Eric Evans 出版了其最具影响力的著名书籍 Domain Driven-Design architecture,其中提出的领域驱动设计(DDD)方法打破了分析和设计割裂的状态,并给出了领域模型的概念,抛弃了将分析与设计分开的做法,使用统一的模型来满足分析与设计的需求,使系统开发能够更加灵活、快速地响应需求的变化。
注意:DevOps 的出现又进一步填平了开发和部署之间的鸿沟,值得注意的是,任何新技术或概念都不是人们凭空想象出来的,都是为了解决人们在生活和工作中遇到的问题。架构师也需要具备发现系统中的问题并给出相应解决方案的能力。
系统分析与设计的三个发展阶段
下面讲讲系统分析与设计的三个发展阶段。
面向数据驱动分析与设计
面向数据驱动分析与设计可以说是系统分析与设计的第一阶段。
软件设计总是从设计数据库及其字段开始的,这一阶段的特征就是围绕数据库编程,应用系统是典型的两层架构,分为展示层和数据库层。该阶段的典型技术为Delphi和VB等,如图3.18所示。
图3.18
这种面向数据驱动分析与设计的方法导致了过程化的编程思维,因为数据库结构由DBA设计后交由程序员编写大量的SQL语句实现,而SQL语句执行是有先后顺序的,所以程序员大多形成了面向过程的思维方式,长此以往形成了习惯就难以改变。
面向过程(Procedure Oriented)是一种思维方式,在面对一个问题时,我们通常先关注解决这个问题的步骤,即过程。比如对于如何将大象装入冰箱这个问题,我们想到的步骤是:第1步,打开冰箱;第2步,装入大象;第3步,关上冰箱。这就是典型的面向过程的思维方式,虽然这样可以更加直接、有效地解决问题,但是面对更复杂的问题时,解决问题的过程会变得非常复杂和难以理解。
同样,面向数据驱动分析与设计有以下明显缺点。
◎ 不能迅速、有效、全面地认识和反映需求,在这种分析与设计思维中,世界不仅由简单的关系数据组成,还使用关系数据库反映现实需求,这不符合人类的自然思维,是一种扭曲的分析方法。
◎ 系统的性能很难提升,容易导致软件运行时的负载集中在数据库端,使系统变成集中式和高风险的大型单体模式(Monolithic),丧失分布式集群处理能力。
◎ 面向对象的编程语言和关系型数据库本身是矛盾的,因为关系型数据库分析与设计本身是面向过程的(这一矛盾在当今的实现中依然存在,不过在领域驱动设计中已有解决方案)。
面向对象和服务分析与设计
随着系统的复杂度越来越高,面向数据驱动分析与设计所存在问题也越来越明显,因此产生了具有划时代意义的面向对象和服务分析与设计的方法,应用系统也变成了经典的三层架构:展示层、业务逻辑层和数据访问层,如图3.19所示。
图3.19
此时出现独立进行分析与设计的两个阶段,系统分析与设计开始上升到一个更高的层次,拥有自己的一套科学且艺术的方法论,但也带来了一个致命的缺点:分析阶段和设计阶段不能很好地衔接,出现了难以逾越的鸿沟,因为分析人员负责从需求领域中收集基本概念,而设计人员负责指明一组能在项目中适应编程工具构造的组件,这些组件必须能够在目标环境下有效执行,并能够正确解决应用程序出现的问题。
可以看到,分析阶段和设计阶段的目标并不一致:分析人员只关注需求分析,并不关注是否适合设计或者能否导出适合设计的分析结果;设计人员发现分析结果过于简单,无法进行编码实现。于是,分析阶段和设计阶段无法对接,导致整个项目无法顺利进行,以失败告终。
另外,在分析阶段和设计阶段虽然都使用了UML,但是UML不是思想方法,只是一种分析与设计工具。假若将UML类比为CAD绘图软件,那么会CAD的绘图员就是建筑师吗?显然不是。所以,UML不是银弹,更不等价于分析与设计方法。
面向问题域分析与设计
问题域模型有一个流行的名字:领域模型,是对现实世界或领域中的对象的可视化表示,可分为概念模型、领域对象模型和分析对象模型。
Eric Evans 在 2004 年 发 表 了 Domain-Driven Design-TacklingComplexity in the Heart of Software的论文,主题便是领域驱动设计,还提出领域模型的分层架构,将整个系统划分为基础设施层、领域层、应用层和用户接口层,如图3.20所示。
图3.20
领域建模是一种艺术,融合了分析阶段和设计阶段,目的是使复杂的软件快速应付变化。领域模型同时适用于分析原型和程序设计,如果一个模型在实现时不具备可行性,就需要重新寻找新的模型,如果该模型没有忠实表达领域的关键概念,则也必须重新寻找新的模型。所以,领域建模的过程把分析阶段和设计阶段变成了单个循环阶段,把分析与设计紧密联系起来,使领域建模专家不再只关注需求概念的收集,也关注程序代码的设计与实现。