如何确定关键需求?
文章目录
- 一、什么决定了架构?
- 1、用例驱动论:只关注功能,不够
- 2、质量决定论:只看质量,不够
- 3、经验决定论:只凭经验,不够
- 二、关键需求决定架构
- 为什么"目标错误"比"遗漏需求"更糟糕?
- 为什么只关注关键需求?
- 关键需求包括哪些?
- 三、如何确定关键需求?
- 1、确定关键质量:权衡质量属性之间的关系
- 2、确定关键功能:4条启发规则
- 四、实际案例:小系统与大系统的架构分水岭
- 案例:项目管理系统
- 场景1:小型PMIS(项目型ISV背景)
- 场景2:大型PM Suite(产品型ISV背景)
- 场景3:多个自主产品组成的方案(例如IBM)
- 对比分析
- 五、总结
核心观点:
- 功能、质量、约束这三类需求都影响架构,但影响方式不同。
- 关键需求决定架构,其余需求验证架构。这是现实,也是策略。
- "目标错误"比"遗漏需求"更糟糕,确定关键需求要一次做对。
很多架构师都有这样的困惑:需求那么多,到底该关注哪些?有人说看用例,有人说看质量,还有人说凭经验。其实,真正决定架构的,不是所有需求,而是"关键需求"。
一、什么决定了架构?
关于"什么决定了架构",主要有三种说法,但都不完整:
1、用例驱动论:只关注功能,不够
问题1:需求不只是功能
需求 = 功能 + 质量 + 约束。用例能很好地描述功能需求,但覆盖不了质量需求和约束需求。
问题2:用例不能完全覆盖非功能需求
RUP自己也搞了个"补充规约"(Supplementary Specification),专门用来记录用例覆盖不了的非功能需求。比如:
- 系统级质量属性(吞吐量、并发数)不能映射到单个功能
- 约束需求(预算、项目周期、技术专利)很宽泛,用例覆盖不了
- 非用户导向的需求(如"可修改性")不适合用用例描述
2、质量决定论:只看质量,不够
《软件架构实践》说"功能在很大程度上独立于结构",但这是不对的。功能和架构是相互影响的,质量和架构也是相互影响的。
表8-1 不同需求影响架构的原理不同
| 需求 | 基本原理 | 对架构设计的影响 |
|---|---|---|
| 功能 | 功能是发现职责的依据 | 每个功能都由一条"职责协作链"完成,架构师通过为功能规划职责协作链、将职责分配到子系统、为子系统界定接口,来推动架构设计 |
| 质量 | 质量是完善架构设计的动力 | 基于当前架构设计中间成果,进一步考虑质量要求,对架构进行细化、调整,甚至推倒重来 |
| 约束 | 约束对架构设计的影响分为几类 | 直接制约设计决策、转化为功能需求、转化为质量属性需求 |
3、经验决定论:只凭经验,不够
经验很重要,但不能成为不思考的借口。架构设计需要方法,不能只凭感觉。
结论:功能、质量、约束这三类需求,都影响架构设计,只是影响的方式不同。但需求那么多,不可能每个都深入分析,需要找出"关键需求"。
二、关键需求决定架构
关键需求决定架构,其余需求验证架构。这是现实,也是策略。
为什么"目标错误"比"遗漏需求"更糟糕?
架构设计是关于"拆分"和"组合"的。如果"拆分和协作"的方式错了,会阻碍其他设计,甚至影响真正需要的质量目标,导致每走一步都偏离正确目标。
实际案例:电商系统的性能优化
场景:电商系统初期运行良好,但随着用户量增长,性能问题凸显。架构师决定优化性能。
错误做法:架构师误以为"数据库性能"是关键需求,决定优化数据库。
- 架构决策:引入数据库读写分离、分库分表、缓存数据库查询结果
- 问题:系统的主要瓶颈不在数据库,而在业务逻辑层的复杂计算
- 结果:数据库优化后,性能提升有限(10-20%),但架构复杂度大幅增加,维护成本提高50%
- 影响:每增加一个功能,都需要考虑分库分表、缓存更新等问题,开发效率降低,系统越来越难维护
正确做法:架构师应该先分析性能瓶颈,发现关键需求是"业务逻辑层的计算性能"。
- 架构决策:优化业务逻辑算法、引入异步处理、优化业务流程
- 结果:性能提升80-90%,架构复杂度增加有限
- 影响:系统性能大幅提升,架构仍然清晰,维护成本可控
对比:
- 遗漏需求:如果遗漏了"日志记录"需求,后期可以添加日志模块,影响有限
- 目标错误:如果选错了关键需求(如上面的例子),会导致架构方向错误,每走一步都偏离目标,后期修改成本极高
关键点:架构设计时"确定关键需求"要一次做对!否则,就像走错方向,走得越快,离目标越远。
为什么只关注关键需求?
这是现实:架构师往往没有时间深入分析"所有需求"。项目进度压力下,必须在有限时间内决定架构设计。
这是策略:把大部分时间和精力投入到最关键的需求上,设计更有效,架构质量更高。否则,对所有需求都浅尝辄止,可能得到一个肤浅的架构。
关键需求包括哪些?
关键需求包括功能、质量、约束三个方面:
- 全面考虑(正确做法):概念架构针对重大需求、特色需求、高风险需求,同时考虑功能、质量、约束
- 只看功能(错误做法):过于理想化,未来修改很大,架构脆弱
其余需求可以用来验证架构,比如以架构方案评审的方式,从每项非关键需求的角度对架构方案进行走查。
三、如何确定关键需求?
确定关键需求,就像找"最重要的20%",把时间和精力花在刀刃上。
1、确定关键质量:权衡质量属性之间的关系
不同质量属性往往相互制约,架构师必须权衡哪些属性是主要目标。
质量属性关系矩阵展示了不同质量属性之间的关系:
- **“+”**表示行促进列(如"持续可用性"促进"可靠性")
- **“-”**表示行影响列(如"互操作性"影响"安全性")
关键点:矩阵中任何一个"减号",都表示潜在风险。架构师要优先考虑关键质量属性。
常见制约关系及实际案例:
案例1:互操作性 vs 安全性
- 制约关系:要互操作,可能降低安全性
- 实际场景:企业级PM Suite需要与需求管理系统、测试管理系统集成
- 如果只看互操作性:设计开放的API接口,支持多种协议,方便集成,但可能暴露敏感数据
- 如果只看安全性:设计严格的访问控制,数据加密,但可能影响集成效率
- 正确的做法:确定关键质量是"互操作性",但必须兼顾安全性。设计统一的认证授权机制,API接口支持OAuth2.0认证,数据传输使用HTTPS加密,既保证互操作性,又保证安全性
案例2:可移植性 vs 性能
- 制约关系:要可移植,可能影响性能
- 实际场景:系统需要支持Windows、Linux、Unix多个平台
- 如果只看可移植性:使用Java等跨平台语言,使用标准库,但可能无法利用平台特定优化
- 如果只看性能:使用平台特定的优化技术(如Linux的epoll),但可能无法移植到其他平台
- 正确的做法:确定关键质量是"性能"(高并发系统),但必须兼顾可移植性。使用Java NIO等跨平台高性能技术,在抽象层使用平台特定优化,既保证性能,又保证可移植性
案例3:持续可用性促进其他质量属性
- 促进关系:持续可用性促进可靠性、鲁棒性、可扩展性等
- 实际场景:金融系统需要7×24小时运行
- 如何影响架构:设计高可用架构(主备、集群、负载均衡),这些设计同时提升了可靠性(故障恢复)、鲁棒性(容错能力)、可扩展性(水平扩展)
约束对质量的影响:
| 约束因素分类 | 约束因素 | 对架构(特别是质量)的影响 |
|---|---|---|
| 经济因素 | 成本收益 | 预算大小影响技术选择;影响可重用性、可维护性、可移植性 |
| 上市时间 | 影响招聘水平、技术选择;可通过购买模块或平台减少开发工作量 | |
| 客户群 | 多国语言 | 需要架构支持多语言 |
| 移动与便携 | 影响支持的协议、客户端;影响可移植性 | |
| 企业现状 | 遗留系统的集成 | 影响互操作性 |
| 企业人员和部门分布 | 影响分布式系统架构、可维护性、安全性 | |
| 未来发展 | 期望的系统生存期 | 影响可扩展性、可移植性 |
| 阶段性计划 | 影响可重用性、可扩展性、可移植性 | |
| 其他因素 | 法律法规 | 影响可扩展性、可修改性、可维护性 |
| 竞争对手 | 影响技术选择、易用性 |
实际案例:约束如何转化为需求
案例1:预算约束转化为质量需求
场景:项目预算有限,只能选择开源技术栈。
约束:预算有限,不能购买商业软件
如何转化为需求:
- 转化为质量需求:可维护性(开源技术栈,需要团队自己维护)、可移植性(开源技术栈,不绑定特定厂商)
- 如何影响架构:选择成熟的开源技术栈(如Spring、MySQL),设计时考虑可维护性(代码规范、文档完善)、可移植性(避免使用特定平台的特性)
案例2:上市时间约束转化为功能需求
场景:产品必须在3个月内上线,否则错过市场窗口。
约束:上市时间紧迫,不能从头开发所有功能
如何转化为需求:
- 转化为功能需求:购买或集成第三方模块,而不是自己开发
- 如何影响架构:设计时考虑集成能力,预留集成接口,选择支持集成的技术栈
案例3:遗留系统约束转化为质量需求
场景:企业已有需求管理系统、测试管理系统,新系统必须与它们集成。
约束:必须与遗留系统集成
如何转化为需求:
- 转化为质量需求:互操作性(必须支持与遗留系统的数据交换、协议兼容)
- 如何影响架构:设计集成层,支持多种协议(REST、SOAP、消息队列),设计数据转换模块,处理不同系统的数据格式差异
2、确定关键功能:4条启发规则
关键功能需求是那些涉及模块最多、或代表最典型协作方式的功能。
任何功能需求都是由特定的"模块协作链"完成的。由于功能需求数量多,很多"模块协作链"是相似的。架构师可以通过分析少数关键功能需求,简化架构设计。
确定关键功能的4条启发规则:
规则1:核心功能
业务层接口中体现的功能。比如项目管理系统中,“查看项目信息”、"添加任务"等。
为什么这些是核心功能?
- 查看项目信息:涉及项目信息模块、权限模块、数据访问模块的协作,是典型的模块协作链
- 添加任务:涉及任务管理模块、项目关联模块、通知模块的协作,需要多个模块配合
如何影响架构?
通过分析这些核心功能,架构师可以发现:
- 需要哪些模块(项目信息模块、任务管理模块、权限模块等)
- 模块之间的协作关系(项目信息模块调用权限模块检查权限,调用数据访问模块获取数据)
- 模块的接口定义(项目信息模块需要提供查询接口,任务管理模块需要提供创建接口)
如果选错核心功能会怎样?
如果架构师只关注"系统配置"、"用户管理"这些管理功能,可能会设计出适合管理系统的架构,但无法支撑核心业务功能,导致:
- 核心业务功能实现困难,需要大量修改架构
- 模块职责划分不合理,协作效率低
- 后期需要重构,成本高
规则2:必做功能
由客户背景决定。查阅"愿景与范围文档",其中"项目愿景解决方案"中的"关键特性",往往是"必做"的候选。对于业务系统,一般"运营"功能的优先级高于"管理"功能。
实际案例:银行系统
愿景文档中的关键特性:
- “支持多种凭证类型”(银行卡、存折、存单)
- “支持账户状态管理”(正常、挂失、冻结、销户)
- “支持利率调整”(执行现行利率)
为什么这些是必做功能?
- 支持多种凭证类型:这是银行系统的核心业务特性,如果不支持,系统无法使用
- 支持账户状态管理:这是银行系统的业务规则,如果不支持,无法满足业务需求
- 支持利率调整:这是监管要求,如果不支持,系统无法上线
如何影响架构?
- 凭证类型:需要设计凭证的继承体系(凭证基类,银行卡、存折、存单继承),需要设计凭证管理模块
- 账户状态管理:需要设计状态机模块,支持状态转换和状态检查
- 利率调整:需要设计利率管理模块,支持利率的配置和生效
如果忽略必做功能会怎样?
如果架构师只关注"账户查询"、"转账"这些常见功能,忽略了"利率调整"这个必做功能,会导致:
- 系统上线后,发现无法支持利率调整,需要紧急修改
- 架构没有预留利率管理模块,修改成本高
- 可能影响系统上线时间,甚至导致项目失败
规则3:高风险功能
风险高的功能应该纳入。比如在线书店的全文搜索:
为什么这是高风险功能?
- 用户视角:搜索慢或"系统忙"是不可接受的。用户搜索"Java编程",如果系统响应慢或提示"系统忙",用户会立即离开,去竞争对手的网站。
- 架构视角:这个功能使用数据库的方式是"面级、只读"的,不同于"点级、写"的操作(添加/修改图书)。
- 添加/修改图书:点级操作,只涉及单条记录,写操作,性能要求不高
- 全文搜索:面级操作,涉及全表扫描或全文索引,读操作,但性能要求极高
如果选错关键需求会怎样?
如果架构师只关注"添加图书"、"修改图书"这些核心功能,可能会设计出适合点级写操作的架构(比如简单的CRUD架构)。但这样的架构无法支撑全文搜索的高性能要求,导致:
- 搜索响应慢,用户体验差
- 系统在高并发搜索时崩溃
- 需要后期重构,成本高
正确的做法:
早期识别全文搜索为高风险功能,进行针对性的架构设计:
- 引入全文搜索引擎(如Elasticsearch),而不是只用关系数据库
- 设计读写分离架构,搜索走搜索引擎,写操作走数据库
- 设计缓存机制,缓存热门搜索词
- 设计异步索引更新机制,保证搜索的实时性
规则4:独特功能
覆盖了上述3类功能没有涉及的职责。比如输入法软件"搜狗拼音"的"在线词典更新"功能。
为什么这是独特功能?
- 核心功能(如"输入汉字"、“词库管理”)主要涉及本地处理
- 必做功能(如"拼音输入"、“词频统计”)主要涉及本地算法
- 高风险功能(如"智能纠错")主要涉及本地计算
但"在线词典更新"功能完全不同:
- 需要与服务器交互,下载最新词库
- 需要处理网络异常、断点续传
- 需要处理版本冲突、数据同步
如果忽略这个功能会怎样?
如果架构师只关注本地功能,可能会设计出纯本地架构,没有考虑网络交互模块。当需要添加"在线词典更新"功能时,发现:
- 没有网络通信模块,需要重新设计
- 没有数据同步机制,需要重新设计
- 架构不支持这种"客户端-服务器"交互模式
正确的做法:
早期识别"在线词典更新"为独特功能,在架构中预留:
- 网络通信模块(负责与服务器交互)
- 数据同步模块(负责处理版本冲突、断点续传)
- 互操作性模块(负责处理不同版本的协议兼容)
这样,当需要添加其他在线功能(如"云词库"、“用户词库同步”)时,架构已经支持了。
注意事项:
- 没有"标准答案":关键功能子集的价值,在于能否有效覆盖架构的不同"职责模块",并反映这些模块之间的协作关系。
- 比例不能一刀切:RUP说"大概占总数的20%至30%",但只有5个功能的系统,如果按20%选,只有1个关键功能,显然不合适。建议:功能少的系统比例高些,功能多的系统比例少些。
四、实际案例:小系统与大系统的架构分水岭
架构设计只有合适,没有最好。无视条件差异照抄架构,危险。
案例:项目管理系统
架构师小李经常用"拿来主义"做架构设计,但这次设计"项目管理系统"的架构时,他困惑了:架构要不要支持集成?如果要,怎么支持?
场景1:小型PMIS(项目型ISV背景)
系统定位:部门级应用,供客户某部门的几十号人使用。
关键需求分析:
关键功能:制定项目计划、分配项目任务、跟踪项目进度
- 为什么是关键功能? 这些是业务层接口中体现的核心功能,涉及任务管理、资源管理、进度管理等核心模块的协作
- 如何影响架构? 这些功能需要任务管理模块、资源管理模块、进度管理模块协作,架构师需要设计这些模块的职责划分和接口定义
关键质量:易用性、维护简单(B/S架构)
- 为什么是关键质量? 部门级应用,用户技术水平不高,易用性直接影响系统接受度;维护简单意味着降低运维成本
- 如何影响架构? 选择B/S架构,用户只需浏览器,无需安装客户端;选择简单的技术栈,降低维护成本
关键约束:控制成本(选择团队熟悉的开发技术)
- 为什么是关键约束? 项目型ISV,预算有限,必须控制开发成本
- 如何影响架构? 选择团队熟悉的Java + Spring + MySQL,而不是新技术栈,降低学习成本和开发风险
架构选型:简单的B/S架构(Web层、业务层、数据访问层、数据持久层),不支持集成。
为什么这样选?
- 不支持集成:部门级应用,不需要与其他系统集成,如果设计集成层,会增加开发成本和复杂度,但用不上
- 简单分层:四层架构足够,不需要复杂的微服务架构,因为用户量小、功能简单
- 技术选型:Java + Spring + MySQL,团队熟悉,开发快,成本低
如果选错关键需求会怎样?
如果架构师误以为"集成"是关键需求,设计了支持集成的架构(如API层、集成层),会导致:
- 开发成本增加30-50%,但功能用不上
- 架构复杂度增加,维护成本高
- 项目可能因为成本超支而失败
场景2:大型PM Suite(产品型ISV背景)
系统定位:企业级应用,统一的项目管理平台,可以与需求管理系统、测试管理系统等无缝集成。
关键需求分析:
关键功能:项目组合分析、项目组合监控、项目关联管理、生命周期管理
- 为什么是关键功能? 这些功能涉及多个项目的关联、跨项目的资源协调,需要项目组合管理模块、项目关联模块、生命周期管理模块的复杂协作
- 如何影响架构? 需要设计项目组合管理模块、项目关联模块,这些模块需要支持跨项目的数据查询和统计
关键质量:互操作性(与需求管理、测试管理等系统集成)、安全性、可扩展性
- 为什么互操作性是关键质量? 企业级应用,必须与现有系统(需求管理、测试管理、OA、HR等)集成,否则无法推广
- 如何影响架构? 必须设计集成层、API层,支持与第三方系统的集成;必须考虑安全认证、数据同步、协议兼容等问题
- 为什么安全性是关键质量? 企业级应用,涉及敏感数据,安全性直接影响系统接受度
- 如何影响架构? 需要设计统一的安全认证模块、权限管理模块、数据加密机制
关键约束:支持二次开发、建立集成平台
- 为什么是关键约束? 产品型ISV,需要满足不同客户的个性化需求,必须支持二次开发
- 如何影响架构? 需要设计插件机制、扩展点、API接口,让客户可以基于平台进行二次开发
架构选型:支持集成的架构(展现层、集成层、API层、业务逻辑层、数据访问层),或者像IBM Jazz那样的集成平台。
为什么这样选?
- 必须支持集成:企业级应用,必须与现有系统集成,否则无法推广。如果设计成不支持集成的架构,客户会拒绝使用
- 集成层设计:设计专门的集成层,负责与第三方系统的数据交换、协议转换、安全认证
- API层设计:设计统一的API层,对外提供标准接口,支持二次开发和第三方集成
- 平台化设计:像IBM Jazz那样,设计成集成平台,不仅支持自己的产品,还支持第三方产品集成
如果选错关键需求会怎样?
如果架构师误以为"开发成本"是关键需求,设计了简单的B/S架构(像场景1那样),会导致:
- 无法与现有系统集成,客户拒绝使用
- 无法支持二次开发,无法满足个性化需求
- 后期需要重构,成本更高
- 产品无法推广,项目失败
正确的架构设计:
- 展现层:支持Web、桌面客户端、移动端等多种展现方式
- 集成层:支持与需求管理、测试管理、OA、HR等系统的集成,支持多种协议(REST、SOAP、消息队列等)
- API层:提供统一的API接口,支持二次开发和第三方集成
- 业务逻辑层:核心业务逻辑,支持项目组合管理、项目关联、生命周期管理
- 数据访问层:数据访问抽象,支持多种数据源
这样的架构虽然前期开发成本高,但能满足企业级应用的关键需求,产品可以推广,长期收益更大。
场景3:多个自主产品组成的方案(例如IBM)
系统定位:覆盖应用软件生命周期的集成ALM方案,包括从系统分析、建模设计到构建、测试、维护、发布的整个过程。
关键需求分析:
关键功能:作为整合方案,支持全球和跨区域团队开发
- 为什么是关键功能? 作为整合方案,需要支持多个产品(需求管理、测试管理、配置管理等)的协作,需要支持跨地域、跨时区的团队协作
- 如何影响架构? 需要设计统一的数据模型、统一的协作机制、统一的权限管理,让不同产品可以无缝协作
关键质量:开放性(支持与第三方系统集成)、每个产品可独立开发、系统可自由组合
- 为什么开放性是关键质量? 企业级ALM方案,必须支持与IBM、HP、MS等厂商的需求管理、测试管理系统集成,否则无法推广
- 如何影响架构? 必须设计开放的集成标准、开放的API接口、开放的协议,支持第三方系统集成
- 为什么"每个产品可独立开发"是关键质量? 不同产品由不同团队开发,必须支持独立开发、独立发布、独立升级
- 如何影响架构? 必须设计插件化架构、模块化架构,每个产品是独立的模块,可以独立开发和部署
- 为什么"系统可自由组合"是关键质量? 不同客户需要不同的产品组合,必须支持灵活组合
- 如何影响架构? 必须设计平台化架构,核心平台提供基础能力,产品作为插件可以自由组合
关键约束:建立ALM集成标准
- 为什么是关键约束? 作为行业标准,必须建立统一的集成标准,让不同厂商的产品可以集成
- 如何影响架构? 必须设计标准化的接口、标准化的协议、标准化的数据格式
架构选型:像IBM Jazz那样的集成平台架构。
为什么这样选?
- 平台化设计:设计核心平台(Jazz协同服务器、Jazz存储库),提供基础能力(安全、访问、存储、搜索、对话等)
- 插件化设计:每个产品(需求管理、测试管理、配置管理等)作为插件,可以独立开发和部署
- 标准化设计:建立统一的集成标准,支持第三方产品集成
- 多客户端支持:支持Eclipse、Web、Visual Studio等多种客户端平台
如果选错关键需求会怎样?
如果架构师误以为"开发效率"是关键需求,设计了紧耦合的架构(所有产品集成在一起),会导致:
- 无法支持第三方产品集成,市场推广困难
- 产品无法独立开发,开发效率低
- 系统无法灵活组合,无法满足不同客户需求
- 后期需要重构,成本极高
正确的架构设计:
- Jazz协同服务器:核心平台,提供安全、访问、存储、搜索、对话等基础能力
- Jazz存储库:统一的数据存储,支持不同产品的数据存储
- 产品插件:需求管理、测试管理、配置管理等产品作为插件,可以独立开发和部署
- 客户端平台:支持Eclipse、Web、Visual Studio等多种客户端
- 集成接口:支持与Rational ClearCase、Rational ClearQuest等第三方产品集成
这样的架构虽然前期开发成本高,但能满足企业级ALM方案的关键需求,可以建立行业标准,长期收益更大。
对比分析
表8-6 小系统 vs 大系统的对比分析
| 项目 | 小系统 | 大系统 |
|---|---|---|
| 背景 | 部门级应用,项目型ISV | 企业级应用,产品型ISV或类似IBM的企业 |
| 关键需求 | 开发成本优先 | 开发、集成成本兼顾或集成成本优先 |
| 权衡 | 放弃集成需求 | 接受前期开发成本大 |
| 集成 | 无集成 | 通过个性化开发或建立ALM集成标准 |
| 架构选型 | 简单的B/S架构 | 支持集成的架构或集成平台架构 |
关键点:小系统和大系统的架构不一样,因为它们的"关键需求"不一样。架构设计只有合适,没有最好。
五、总结
[用列表形式总结价值点]
- 功能、质量、约束都影响架构:用例驱动论、质量决定论、经验决定论都不完整
- 关键需求决定架构,其余需求验证架构:这是现实,也是策略
- "目标错误"比"遗漏需求"更糟糕:确定关键需求要一次做对
- 确定关键质量:使用质量属性关系矩阵,权衡相互制约的关系
- 确定关键功能:从核心、必做、高风险、独特功能中找,功能少的系统比例高些
- 考虑约束影响:约束可能转化为功能需求或质量需求
- 实际应用:小系统和大系统的关键需求不一样,架构选型也不一样
因此,架构师要做的,不是分析所有需求,而是找出"关键需求"——那些真正决定架构的需求。通过确定关键质量、关键功能、关键约束,架构师可以在有限时间内,设计出合适的架构。
