3. Pre-architecture总论

架构设计对系统成败非常关键,那么,什么对架构设计的成败非常关键呢?

凡是预则立,不预则废。 -- 孔子,《礼记.中庸》

业内对架构的讨论沿用了传统思路:如果知道了系统需求,就可以此系统构建架构,这种观点是缺乏远见的...... -- Len.Bass 《软件架构实践(第2版)》

功能需求、质量属性及约束共同决定了架构,对这3类需求的把握是否到位、设计是否对路,是架构设计成败的关键所在!

然而,业界的现状却是:

  • “架构师就是技术高手”的声音充耳不绝,我们常错误地认为“架构师不必懂需求”。例如,许多不知道业务级需求、用户级需求、开发级需求 包含的具体内容,更不懂功能、质量、约束 对架构设计的影响如何大相径庭。
  • 只有少数经验深厚的架构师在“拿到”需求之后,会基于业务背景、系统规模、技术趋势、开发团队现状等现实情况,对需求进行理性的、有针对性的权衡、取舍、补充、而在方法一级,Pre-architecture阶段基本是空白的。

期望能够在方法一级为“Pre-architecture阶段”提供较明确的指导。核心的“四步法”:

  1. 需求结构化
  2. 分析约束影响
  3. 确定关键质量
  4. 确定关键功能

3.1. 什么是Pre-architecture

我认为,完整覆盖“需求进,架构 ”的架构设计方法才是符合需要的。

Pre-architecture就是架构设计的最前期阶段,其工作目标包括:理解需求、建立需求大局观,确定架构设计方向等

“磨刀不误砍柴工”。如果说“CA”阶段和“RA”阶段是“砍柴”(这两个阶段都对系统进行了某种程度的切分,系统已经不再是“黑盒子”了),那么最初的Pre-architecture阶段就是“磨刀”(此阶段未对系统进行切分,系统还是“黑盒子”)。

3.2. 实际意义

Pre-architecture阶段虽然是铺垫性质的阶段,但对架构实践而言意义重大。

3.2.1. 需求理解的大局观

架构师常常面对相互矛盾的需求目标。如果对需求的理解缺乏大局观,那将如何进行需求的权衡取舍?

重大需求塑造概念架构 。如果对需求的理解缺乏大局观,那将如何识别重大需求、特色需求、高风险需求?

Pre-archiecture阶段能帮助架构师建立需求理解的大局观。任何需求都可定位与业务级需求用户级需求开发级需求 这3个需求层次的某一层,同时也必属于功能质量约束 这3类需求的某一层。

如此一来,就便于梳理脉络、把握关系。

3.2.2. 降低架构失败风险

对需求理解不透、遗漏需求往往是架构设计失败的重要原因。在你的身边,一定有类似 2. Pre-architecture的故事 那样的案例。

3.2.3. 尽早开始架构设计

如何尽早开始软件架构设计?这是很多软件企业非常关心的一个问题,因为大家都深感工期的巨大压力

灵活运用Pre-architecture阶段的方法,有一个额外的好处:能够在需求没有“全面完成”的情况下开始架构设计。

具体而言,为了尽早开始架构设计,软件企业必须做好以下两点:

  • 让架构师参与需求分析工作

实际上,让架构师相对自由的“全程”参与需求分析工作--甚至可以不为任何具体的需求捕获、需求分析、需求文档工作负责

  • 不能被动等待完善的产品需求

建议架构师在参与需求分析工作是,不断运用ADMEMS矩阵等工具对需求进行大局的梳理,只要满足下列3个条件,就可以尽早开始进行架构设计工作。

  1. 有了明确的业务需求。 必须保证甲、乙双方就建设系统的目标(可能不止一项)达成共识,《愿景文档》经过了正式评审,并明确了投资、工期标准、整合等约束条件。试想,业务需求含糊不清,架构设计方向如何确定呢?
  2. 了解全面的用户需求 。也就是说,系统能帮助用户干什么、不能干什么,这个“需求的Scope”已经非常明确了。如果采用了用例技术,则表现为“用例图”是比较完善的,没有明显遗漏

    注意用例图和用例规约在需求分析中的实践意义不同,可参考《软件架构设计》一书

  3. 有了典型的行为需求 。这意味着,大量需求还未明确定义,离提交《软件需求规格说明书》还早。如果采用用例技术,则表现为核心功能的《用例规约》已定义。

3.2.4. 明确架构设计的“驱动力”

架构设计的“驱动力”不就是《软件需求规格说明书》吗?这种观点,只对了一半。

  • 问题1:试想,《软件需求规格说明书》中几乎没有定义非功能性需求 (客户也签字了),架构设计师就可以不考虑非功能性需求了吗?
  • 问题2:试想,需求变更难以避免 ,如果以所有需求作为架构设计的“驱动力”会是什么结果?
  • 问题3:试想,《软件需求规格说明书》中照抄了《ISO 9126》中所有的质量属性要求 ,架构师应该不计成本,不分重点的全部支持吗?

上面是3个问题,都是日常工作中常见的问题,都说明架构师还需要关注其他很多因素,最终或添加、或减少、或折衷,理性的确定真正的架构设计“驱动力”。

具体而言,Pre-architecture阶段将告诉我们不辱使命的方法:

  1. 分析业务需求和约束背后的衍生需求 --针对问题1.
  2. 发现遗漏需求 --针对问题1.
  3. 确定关键功能 --针对问题2.
  4. 确定关键质量 --针对问题2.
  5. 权衡质量属性之间矛盾关系 --针对问题3.

3.3. 业界现状

既然Pre-architecture阶段如此重要,业界现状如何呢?

很遗憾,业界对Pre-architecture阶段普遍不够重视。相反“架构设计唯靠经验”、“架构设计目标不变”等错误观点比较常见。

我们头脑中的“位置”是有限的,如果错误的认知占据了主导位置会导致实践偏差,必须防止。

3.3.1. “唯经验论”

和“架构师不必懂需求”的误解相比,“唯经验论”已经有所进步了。这种观点认为,架构师纯粹凭借经验,发现需求的遗漏、权衡需求之间的矛盾、确定架构设计的重点目标。

必须承认,经验对架构设计很重要,但“唯经验论”依然是错误的。

因此,世界上并不存在两个完全相同的想,不同的项目在功能需求、质量属性,以及约束这3方面必然存在差异。

于是,架构师不仅应具有一定经验,还必须掌握超越具体项目的、更具有意义的方法和技能。

3.3.2. “目标不变论”

架构设计的目标不是一成不变的,基于此认识,ADMEMS方法在Pre-architecture阶段的“确定关键质量”环境提供了专门的指导。

架构设计目标不变论”是错误的。

例如,有人认为:

我们必须牢记架构设计的总体目标,可概况为以下几点。

  1. 最大化的重用......
  2. 尽可能的简单明了......
  3. 最灵活的扩展性......

首先,若架构设计的目标真能概括为不变的“几点”,那可算是架构师的福音了。

但实际上,架构设计的目标必然会随着领域不同(如航天航空、电信、电子政务)、规模不同(如项目、产品、平台)、条件不同(如工期、预算、标准)而变化。

其次,为重用、简单、可扩展都加了“最”(而不是权衡折中),不符合架构设计的现实,更何况“灵活”和“简单”之间常常存在矛盾。

3.3.3. 需求分类法的现状

软件行业处在不断发展变化中,软件需求分类法就是一例。当前,业界影响最为广泛的需求分类法将需求分为3个层次。

这种需求分类法的最大好处是明确了不同层次之间的跟踪关系--业务需求->用户需求->功能需求。从而建立了需求分析的主要脉络,非常有意义。

但是对以架构师来说,这种需求分类法中的“约束条件”太过狭义了,没有反应“架构设计必须面对来自业务环节、使用环境、构建环境、技术环境的4大类约束 ”这一现实情况。

再例如,RUP提倡的需求分类法也包含3个层次:需要(Need)、特性(Feature)、软件需求。

这类分类法也是主要为需求分析工作服务的,它除了非常倚重用例技术之外,还有一个明显特点--Feature

以特性(Feature)技术作为从需要(Need)想软件需求过过渡的跳板,是解决需求分析中“从需求想软件需求跨度过大”问题不错的选择,这一点已经受到很多实践者的认同。

但是,这个方法中用例的地位过分突出了,又由于“用例涉及但不涵盖非功能需求”的性质,不少实践者遗漏非功能需求的常见问题也就不难解释了。

最后,顺便指明上述两种“需求层次论”的对应关系,此问题令不少实践者困惑。

3.3.4. 需求决定架构的原理还需继续归纳

不懂不同需求分布如何影响架构,就难以进行理性的架构设计,难免“拍脑袋”决策,关于需求决定架构原理,业界当前的认知状况如下:

  • 功能影响架构原理,研究的最透彻
  • 质量影响架构的原理,也有基本共识
  • 约束影响架构的原理在很大成图上被忽视了

3.4. 实践要领

问题是方法之父。不怕有问题,就怕发现不了问题。

3.4.1. 不同需求影响架构的不同原理,才是架构设计的基础

当前业界,大多数架构师都认同“需求决定架构”,但对需求“如何决定”架构还知之不深。

请各位架构师问自己这样一个问题:需求决定架构,真的是这么简单吗?

如果真的这么简单,为何“我”常常对需求已“心知肚明”,却依然对架构设计“一筹莫展”呢?

答案是:“需求决定架构”是对的,但不同需求影响架构的不同原理,才是架构设计思维的基础

“人类知识和人力权利归于以:因为凡是不知原因时,即不能产生结果。......而凡是在思辨中为原因者在动作中则为法则。” -- 哲学家培根

任何一项功能都是有一条特定的“职责协作链”完成的。

作为完整的软件系统,它在支持每一个具体功能时,都必然涉及软件不同“部分”之间的相互配置。系统控制权在这些不同的“部分”之间的来回传递,形成一条“职责协作链”,可以完成非常复杂的功能。

而质量,是完善架构设计的驱动力,不考虑质量的系统是无法走出实验室的

基于中间设计成果进一步质疑是其中基本的“思维方式”

例如:如果只考虑功能,“页面缓存”的设计就永远不会被引入,它是质疑性能、调整设计的结果。

至于约束,则有不同的具体方式影响着架构设计

  • 直接制约设计决策的约束 。例如,“系统运行与Unix平台之上”作为一条约束,架构师直接遵守即可
  • 转化为功能需求的约束 。例如,“本银行系统必须严格执行人民银行统一规定的利率”是一条约束,但分析后发现,正是它引出了一条功能需求:即必须提供调整利率设置的实用功能
  • 转化为质量属性需求的约束 。例如,有经验的系统分析员发现了一条重要约束:“任职于各储蓄所和分理处的柜员,计算机水平普遍不高”。由此,未来的系统必须具有很高的易用性(否则不会用)和鲁棒性(否则可能会把系统搞瘫痪了)就非常必要了

3.4.2. 二维需求观

观念是行为的向导,有什么样的观念存在,就有怎样的行为方式产生--突破拙劣观念的意义就在于此。

作为架构师,如果在你的观念中,需求是一个散乱无序的“列表”,面对复杂系统时就会非常被动。需求列表这种贴着“简单”这个“招人待见”标签的方法以及影响、并正在继续影响着许多一线架构师。

3.4.3. 关键需求决定架构,其他需求验证架构

有经验的架构师,懂得在实践中运用“关键需求决定架构 ”的理念。

  • 功能需求做减法 。在所有功能中挑选一个“关键功能子集”,作为“架构设计驱动力”的第一部分。
  • 质量需求做减法 。根据系统所在领域特点及系统规模等因素,确定架构设计重点支持哪些质量属性,作为“架构设计驱动力”的第二部分。
  • 约束需求做加法 。充分考虑需求方及业务环境因素、用户群及使用环境因素、开发方及构建环境因素、业界当前技术环境因素等“4类约束 ”,将之作为“架构设计驱动力”的第三部分。

3.4.4. Pre-architecture阶段的4个步骤

Pre-architecture阶段对整个架构设计工作非常重要,它担负着建立需求大局观、把握需求特点、确定架构设计驱动力的责任。

首先,将多而杂的架构影响因素梳理脉络、建立全面有序的理解。

然后,分别针对约束、质量、功能这3类需求开展相应工作。

  1. 分析约束影响,识别隐含需求
  2. 确定关键质量,明确关键质量之间的优先级
  3. 确定关键功能,便于更有针对性的分配有限的架构设计时间

下一节:“心念不同,判断力自然不同。” -- 严定道,《格局决定结局》

全面认识需求,是生成出高质量软件所必须的“第一项修炼” -- 温昱,《软件架构设计》
Pre-architecture 阶段包括4个步骤,咱们先讲讲前两步。

* 第1步,需求结构化
* 第2步,分析约束影响