一、概念
软件架构定义—组成派与决策派
软件架构当前没有一个统一的准确定义;
组成派:软件系统的架构将系统描述为计算机及组件(泛指元素,可以是子系统、框架、模块、类等)之间的交互;
决策派:软件架构是在一些重要方面做出决策的集合,包括 系统组织、结构元素和之间接口/交互行为,如何组合元素逐渐合成 以及 指导其组织的架构风格; 同时也涉及其他特性:使用、功能性、性能、弹性、重用,可理解性、经济和技术限制及权衡,以及美学。
总而言之,软件架构主要涉及以下几方面:
分割与交互:组件的划分与交互。层次决策:如何划分原则,模块职责定义,接口定义,交互机制定义,技术选型,质量属性要求,变化适应。
组件(UML规范中的定义):组件代表系统模块化的一个部分,他封装了自身的内容,在环境中它的表现是可替换的。
一个组件根据供给接口和需求接口定义它自己的行为。同样的,一个组件也属于某一个类型,其一致性有这些供给接口和需求接口来定义。只要这两个组件的类型一致,组件是可以替换的。
架构设计的原则—看透需求/把握大方向/设计各个维度
看透需求
这是基础,要做到“理解了,能说所以然” ,关键需求决定 概念架构。
1、需求要全 2、要梳理需求间矛盾约束 3、追溯关系(需求分层、每个开发特性都能梳理到 客户层面的业务目标)
架构大方向正确
架构设计层面 只关注 非常重要的 拥有长期和持久效果的元素,如那些主要的结构组件和基本行为,一般不关注内部细节。架构不是一层不变的,随着时间演变、需求的提炼、风险的识别,重要的元素可能发生改变,此时架构的稳定性某种程度体现了架构是否优秀的标准。
设计好架构的各个方面
大型软件架构设计是非常复杂的,需要从多个方面进行架构设计,运用多视图设计方法。
架构平衡的要素—来自多方面的诉求
最终用户的需求和直观正确的行为、性能、可靠性、可用性、实用性、安全性;
系统管理员的需求和直观的行为、管理以及帮助监控的工具。
市场人员的需求和竞争性、市场时机、与其他产品的定位及成本相关。
消费者的需求和成本、稳定性、及进度相关。
开发人员的清晰需求、简单一致的设计方案相关。
相关经理的需求和项目追踪的可预见性、进度、资源产出率及预算有关。
维护人员的需求和易于理解、可靠性、及包含文档的设计方法有关、进行修改的容易程度相关。
二、架构的设计过程
1、需求分析—来源/完整性/设计转化
全面的认识需求(功能性需求 和 非功能性需求),涵盖 功能、质量、约束 三方面。 并 权衡 不同需求之间相互影响。
需求来源—愿景分析+需求分析
愿景分析:愿景=业务目标+范围+特性+上下文描述
一般由新需求方或者软件供应商组织,阐明 业务需求、描述需求生产的背景和理由等。
输出 《愿景与范围文档》,包括内容:1、业务需求(背景/机遇/目标/客户及市场需求/价值/风险)2、愿景解决方案(愿景陈述/主要特征/假设与依赖环境)3、范围和局限性(首次发布范围/后续发布范围/局限性/专用性) 4、业务环境(客户概貌/项目优先级) 5、产品成功因素。
需求分析
通过需求采集,分析活动定义输出《软件需求规格说明书》SRS:software Requirements Specification。精确的阐述系统必须的功能、必须达到的质量属性目标。
《软件需求规格说明书》包含内容:1、前言(目的、范围、定义 缩写词 略语、参考资料)2、需求概述(用例模型-用例图、限制与假设) 3、具体需求 (用例描述、外部接口需求-用户/硬件/软件/通信 接口、质量属性需求-性能/易用性/安全性/可维护性、设计和实现约束-遵循标准 硬件限制)
需求的完整性—多维度多层次
需求的完整性分析非常重要,必须全面的掌握需求。需求是分层次的、需求也是多维度的。要从 来自多方面的诉求 中 按 功能/质量/约束 识别是否有遗漏。
推荐的软件质量属性分类:
1)运行时期质量属性:性能/安全性/易用性/持续可用性/伸缩性/互操作性/可靠性/鲁棒性;
2)开发时期质量属性:易理解性/可扩展性/可重用性/可测试性/可维护性/可移植性;
约束需求分类:
1)业务环境因素:时间 预算 、业务规则限制、法律法规、专利限制等;
2)使用环境因素:提供给何阶用户,用户年龄段偏好、用户国家、使用环境干扰条件等;
3)构建环境因素:开发条件技术水平、磨合程度、成员分布、开发管理、源代码保密等;
4)技术环境因素:技术平台、中间件、编程语言、技术发展趋势;
需求转向设计的关键思维
1、功能需求是 发现职责的依据
每个功能都是职责协作链的一环,通过功能规划让职责分配到子系统、为子系统界定接口、确定基于接口的交互机制、推动架构设计进行。
2、质量需求 是 完善架构设计的动力
架构设计过程进一步考虑质量需求,对架构中间进行设计细化、调整、甚至可能推倒重来,一步步完善架构设计。
3、约束需求 是 架构设计对应 风险/影响 分类调整
部分约束需求 要转化为设计决策(如 系统运行与unix平台),转化为功能(如 需要 基于系统执行现行利率计算-利率调整),转化为质量属性需求约束(柜员计算机水平不高–易用性)
2、领域建模—概念的可视化抽象
开发人员 “惧怕” 一个领域,主要问题是 “行话” 听不懂,看不懂;领域模型 就是 将领域的概念 以可视化的方式 抽象为一个或者一套模块(如UML表示)。
透过问题领域的重重现象,捕捉背后稳固的领域概念,为 项目成员/客户交流体概念提供共同认可的语言核心。随着项目进展,模型逐渐精细化。
领域建模 输入 一是 功能 、二是 可扩展性要求。要支持 现在的功能,还应该考虑 随着 业务发展 可能出现的未来功能。业务决定功能,功能决定模型,一定是从 目标->需求->模型;
典型问题-过多的假设—促进用户沟通
当用户参与度不够 或者 不够深入,容易引起需求分析成功中过多的假设成分。需要通过 借助 需求讨论、原型评审、现场客户等方法 拉动 客户代表或者领域专家 深入参与建模。避免需求分析员理解一直停留在假设层面。
典型问题-领域复杂度过高—渐进清理
需求分析过程 ,针对 关键领域问题理解不深,会引起卡壳或者争论不休,难以推进。可以使用 领域建模 循序渐进的理清领域知识,每弄清楚一部分 就在项目组公开。撒上一层土,夯实了,再撒上一层土。
3、确定关键需求—众说纷纭 到 真知灼见 到 付诸行动
优秀的设计并不是按部就班的自顶向下或自底向上方法,而是着眼于权重更大的目标,先致力于难点的设计并消除其中的疑惑。
关键需求决定了架构;架构设计 并不是 用例驱动 / 质量驱动 / 经验驱动,而是关键需求。目标错误比遗留需求更糟糕。
对需求进行筛选,对非功能需求进行综合权衡,确定对软件架构起关键作用的需求子集。
确定关键质量
为了提高软件系统认可度,识别应该要重点提升哪些方面的质量属性。分析这些质量属性中间 相互制约或者促进关系,调整其标准。
确定关键功能
关键的功能需求,经常为 涉及(串起)的模块最多,协作方案最有代表性的功能需求。从四个反面出发:1)核心功能 2)比做的功能 3)高风险功能 4)独特的功能(未被前三中包含的);
4、概念架构设计
概念架构是针对 重大需求、特色需求、高风险需求,形成稳定的高层架构设计成果。直指系统目标的设计思想和重大选择(仅仅关注高层组件和交互关系,不涉及接口细节)。
通过多个概念涉及备选方案,评审选择。同时重视关键功能和关键质量,明确1个决定和4个选型:
1)如何划分顶级子系统 ;
2)架构风格选型;
3)开发技术选型;
4) 集成技术选型
5)二次开发技术选型;
5、细化架构设计
多维度细化设计,一般分别从 逻辑架构、开发架构、运行架构、物理架构、数据架构 等不同架构视图进行设计。
从2视图(逻辑视图+物理视图)到 5视图 细化
逻辑视图(职责划分)
职责划分:确定逻辑层、子系统、子模块、关键类;
职责间协作:确定接口和协作关系;
UML可选: 包图/类图/对象图 序列图/协作图/状态图/活动图
模块合理划分方法:
1、从需求层面“功能树”出发 ,启发 功能模块 划分;
2、水平分层,促进模块分解;
3、通用模块和通用机制识别;
4、现代的用例驱动 模块划分;
5、传统的模块思维
开发视图(层序单元组织)
确定程序单元:源文件(开发语言)、配置文件、目标单元;
确定单元组织:project划分、project目录结构、编译依赖关系;
UML 可选: 包图/类图/组件图
运行视图(控制流组织)
控制流:进程、线程、中断服务程序
控制流组织:系统启动与停机、控制流通信、加锁与同步
UML 可选: 包图/类图/对象图 序列图/协作图
物理视图(物理节点安排)
物理节点:pc、服务器、单片机、部署、烧写、系统软件选型
物理节点拓扑:连接方式、拓扑结构、物理层、冗余考虑
UML 可选: 部署图/组件图
针对物理节点 要从思维层面思考4个优化点:
1)如何降低节点内 计算开销
2)如何降低节点间 通信开销
3)如何避免节点内 cpu/内存/硬盘 资源争用
4)如何避免节点间 网络带宽 冲突
数据视图(持久化设计)
持久数据单元:文件、关系数据库、实时数据库
数据存储格式:文件格式、数据库Schema
6、架构验证
好的策略 必须一再求证、测试、发现瑕疵漏洞弥补不足,有时甚至得全盘放弃 重新规划。针对 对后续工作产生重大返工代价的工作进行验证。往往需要开发架构原型,并对原型进行测试和评审。
三、模块划分专题
架构的模块划分常见思路
1)自顶向下 (水平切分 分层,垂直切分 分模块)
2)自底向上(先识别类、归纳模块思路–用例驱动)
3)拍脑袋(依靠经验和灵感 进行切分)
分层设计技巧
常见的分层模型:
展现层+业务层+数据层、UI层(界面)+SI层(系统交互)+PD层(问题领域)+DM层(数据库管理)
分层关键上下文:
1、外部用户:终端用户、管理员
2、文件或者数据库等持久化存储设施
3、外部系统与底层硬件
4、时限出发机制。
分层思考点:
1、UI 交互层是否存在?
2、UI交互层职责包含哪些部分?(如管理员/用户/报表 界面)
3、系统交互层是否存在?包含几部分(有哪些外部交互系统、采用专用sdk、特定协议 还是其他方式)
4、数据管理层是否存在?包含几部分(有没有持久化需要:flash存储、文件、数据库)
5、问题领域层职责包含哪几部分
细粒度模块划分技巧
1)分层细化
2)分区(职责)封装
3) 通用模块分离
4) 通用机制框架化。
借助功能树驱动模块划分
功能树是一种框架性工具,有助于需求分析人员逐层确定系统必须的功能特性。(注意需求再细节 也不应该涉及实现、应该时黑盒的);
功能树 通过 功能大类/功能组/功能项 隶属与支持关系组合。刻画问题领域。通常由需求分析师导出。
借助用例驱动模块划分
从用例到类,再到模块。
用例图 定义系统给外部actor功能,识别用例背后由哪些类(运用鲁邦图 发现所需类),以及涉及类之间的交互(运用时序图 明确类之间的交互关系)。然后通过多个用例识别出这些类,将它们划分到不同模块。