所谓的“开始就是结局”,要达到什么样的结局取决于什么样的开始,结局就是开始的地方。 -- T.S 艾略特,《四个四重奏》
需求验证的目标是尽可能的暴露问题,而不是证明无错。 -- 徐峰,《软件需求的最佳实践》
没有风险的软件早就被开发完了。
作为架构师,首先要面对的风险就是需求。既要关注功能需求,又要平衡互相矛盾的质量属性需求,还不能遗漏各方面的约束性需求...这,已经成为合格架构师必需的基本功。
接下来,3个真实故事都说明了这一点。
2.1. “不就是个MIS吗!”
2.1.1 故事: 外籍人员管理系统
公司接单了,一个市级的外籍人员管理系统。
小周被任命为这个项目的架构师。需求分析阶段,小周也参与了。几天之后,小周就开始“轻敌”了,他在一次项目会上说了这么一句话:“这个项目不就是一个MIS
吗!”
接下来的工作比较顺利,项目组也算情绪高昂......
项目组的情绪急转直下,出现在项目接近尾声的一天,客户方的小崔,看着漂亮的“外籍人员信息录入”界面,弱弱的说了一句,“哦,外籍人员的信息,大部分都不是我们录入的,而是来自省局。”
这些问题大了,最棘手的问题是,项目定义的数据库Schema
和省级系统的数据库Schema
不一致。
- 若飙车不一致状态,就人为造成了数据格式的不兼容,这是典型的烟囱式应用的做法,为未来可能出现的更多整合要求埋下了障碍;
- 若参考省级系统的数据模型重新定义数据库
Schema
,大量代码就必须重写,项目工期必然拖延。
拼命加班......
2.1.2. 探究:哪些因素构成了架构设计的约束性需求
有人说:“错”的一半是“金”,“败”的一半是“贝”。
故事中暴露的问题看似简单:太大意了,遗漏了重要约束性需求。但试问:下次如何避免?......
只有我们这样问自己,才算是“败”中求“贝”。
反思结果可以关注第4章 ADMEMS方法的‘约束性分类理论’
2.2. “必须把虚拟缓存管理裁剪掉”
2.2.1 故事:嵌入式OS的裁剪
系统软件研究室的新任务启动了,对VxWorks
操作系统进行裁剪,并开发专用硬件驱动程序。
团队成员都挺提劲的......
这天,总工程师要听听进展情况,亲临研究室。当小吴开始汇报对OS
虚拟内存管理的“深入理解”时,总工程师的标签有些不大自然。
不久,他打断了小吴,说了这么一句话:“整个系统才有多大内存可用?我们的OS占的内存越多,应用软件可用的内存就越少。所以,必须把OS
的虚拟内存管理裁剪掉,直接访问物理内存。”
举“组”震惊,却又深表折服。
2.2.2. 探究:又是约束
架构设计不仅仅要考虑支持功能、满足质量要求,还要重视各种约束性需求。
这个故事中的“内存有限”,就是嵌入式系统设计中常见的约束。
关注约束,要趁早。
2.3. “都是C++的错,换C重写”
2.3.1. 故事:放弃C++,用C重写计费系统
老郑曾经挺开心。
老郑在某电信软件企业,负责计费系统的架构。最初,他非常重视系统的性能问题,因为他认为:电信领域用户群光,数据量大,所以性能的压力必然会很大。
后来,他们用C++
开发的计费系统上线了,用户反映彼此,性能挺高的。
但现在,老郑很懊恼。
原因何在?原来,计费系统一直面临着功能不断改进的压力,整个团队不断致力于提高系统的可扩展性--以便于增加和修改功能。但始料未及的是,可扩展性上去了,性能下来了!
看着程序里导出都是接口和无处不在的间接、继承,老郑产生了一个危险的念头,都是C++
的错,应该用C
重写计费系统!
2.3.2. 探究:相互矛盾的质量属性
互动问题:
问题:某公司以C
语言替代C++
,重写电信计费系统,因为开发人员引入了太多抽象,导致“可扩展性上去了,性能下来了”。此法可行否?
- A. 能解决问题
- B. 于事无补,因为
C
也会过度设计 - C. 问题出在
Pre-Architecture
- D. 架构设计中必须分析质量之间的互相影响,制定权衡取舍策略
正确答案:B、C、D
高性能和灵活扩展这两个质量属性之间存在矛盾关系,这就是要害。
上面这张图揭示了更多质量属性之间的“促进”或“矛盾”关系。我们可以看到:性能和安全性,与其他许多质量属性都是矛盾的。
正确的做法是:
- 在架构设计之初,就全盘考虑架构设计要重点关注关键质量目标--以老郑为例,性能和可扩展性(当然还会有其他质量属性)都重要。
- 在第一时间就判断这些“关键质量”之间有没有冲突关系,并制定权衡取舍策略--仍以老郑为例,性能和可扩展性矛盾,性能的优先级更高,谨慎评审提高可扩展性的设计对性能的影响后决定是否采用。
2.4. 展望“Pre-architecture阶段篇”
失败的故事,何止3个?透过这冰山一角,我们看到的是一线架构师“把握需求技能的缺失 ”。软件架构师不必是需求捕获专家;但他一定应在需求分类、需求折中和需求变更的研究方面的专家,否则他和优秀软件架构师相比就输在“起跑线”上。接下来,我们来考虑如何建立需求理解的大局观 、如何把握需求特点 、确定架构设计驱动力 。
下一节:架构设计对系统成败非常关键,那么,什么对架构设计的成败非常关键呢?