假设有一座漂亮的大房子,一个人站在房子的前面,一个人站在房子的后面,另外两个人分别站在房子的左右两侧。四个人看房子都有不同的视角,四个人都在争论自己看到的那一面是正确的一面,如果运用水平思考,那么这四个人就会绕房子一圈,分别看到房子前后左右四个面。 -- 爱德华.德.博诺,《六顶思考帽》
总的来说,“架构”一词涵盖了软件架构的所有方面,这些方面紧紧的缠绕在一起,决定如何将之分割成部分和主题显得相当主观。既然如此,就必须引入“架构视点”作为讨论、归纳和理解大型系统架构的手段 -- Peter Herzum, 《Business Component Factory》
架构设计是一门解决复杂问题的实践艺术。于是,以分而治之为思想核心的多视图方法必不可少。
接下来主要介绍支持细化架构设计的整体思路--多视图方法。
12.1. 什么是细化架构
细化架构是相对于概念架构而言的,它们是架构设计的两个层次,分别对应于“概念级”解决方案和“规约级”解决方案。需要注意的是,系统架构属于架构设计,不能和Detailed Design
(详细设计)相混淆。
架构领域最喜欢将建筑设计的多视图方法与软件架构设计的多视图方法做类比,在此就不在进行赘述,而是举一个更贴近生活的例子:装修的多视图方法
- 功能视图
- 布线视图
通过运用装修的两视图法,你的装修设计摆脱在一个图里画来画去(想来想去)的困境。其中,装修设计的功能视图比较多的考虑:
- 家具
- 家电
- 灯
- 窗帘
而布线视图则集中考虑:
- 插座
- 网线
- 电话线
- 有线电视线
我们还发现,功能视图和布线视图是相互影响的,例如插座不能设计在大衣柜的后面,否则无法使用。这与软件架构设计的多视图方法中“兼顾多个视图设计之间的一致性”的要求是神似的,例如架构设计要考虑职责、程序单元、部署节点等要素之间的相互影响。
12.2. 实际意义
关于多视图方法的价值,Len Bass等专家在《软件架构实践(第2版)》一书中论述道:
神经科专科医生、整形医生、血液专家和皮肤科医生对人体结构有着不同的视图。眼科医生、心脏病专家和足病医生研究治疗的是身体的某个部分。运动学专家和精神病专家关注的是整个人体行为的不同方面。尽管这些视图是不同的并且具有差异巨大的属性,但它们都具有内在相关性:它们共同描述了人体的结构 。
软件也是如此。现代系统非常复杂,很难一下领会。相反,在任何时刻,我们只能把注意力放在软件系统的一个或几个结构上。为了有意义的传达架构的信息,必须说明此刻正在讨论哪个或哪些结构--即采用的是架构的哪个视图。
所以,多视图方法有两个方面的实际意义:
- 利于思考 (因为分而治之的思维方式)
- 便于交流 (因为在一定程度上分类了涉众关注点)
12.3. 业界现状
12.3.1. 误认为多视图是OO
方法分支
提问:Framework
技术是OO
的分支吗?不是,Framework
本质上和面向对象无关,用C语言也可以编写Framework
。更切切近本质的Framework
的定义是:可以通过某种回调机制进行扩展的软件系统或子系统的半成品。
的确,OO
方法太流行了,以至于很多技术都“变成”了OO
的分支。
有同行也常常将多视图方法误认为是OO
方法的分支。其实,无论是OO
方法,还是结构化方法,都远未涵盖架构设计的全部。所以,只具有OO
技能对架构师而言是不够的。
12.3.2. 误将“视图”当成“阶段”
对架构设计方法而言,区分阶段和视图的概念是非常重要和必要的 。
“左边”的观点--概念架构、逻辑架构、物理架构是3个不同的层次。其实这种观点不完全正确,因为逻辑架构和物理架构是架构设计同一阶段中须要同时考虑的两个方面--即二者是两个视图,而非两个阶段 。
12.3.3. RUP 4+1视图
在软件架构发展史上,4+1视图方法具有重大贡献。
1995年,Philippe Kruchten发表了题为《The4+1 View Model of Architecture》的论文,标志着4+1
视图方法的诞生。后来,Philippe Kruchten加入Rational
公司,4+1
视图演化为下图所示的模样。
RUP4+1
视图方法有几个重要特点:
- 重视
OO
方法 Use Case
驱动- 强调模型的重要性
对应于上述3个特点,架构师在实践中应注意:
OO
可以指导逻辑架构视图的设计,但是OO
方法对物理视图等的设计指导很弱。另一方面,即使逻辑架构的设计,也未必都是以OO
方法为指导的。例如,大量嵌入式软件系统和系统软件仍以C
语言为主要开发语言,其逻辑架构设计还会以结构化方法为指导。- 用例不是架构设计本身工作。
4+1
视图中的“4”是架构设计,“+1”是驱动因素。 - 建模切忌穷兵黩武。如果一个模型建立中没有启发思维,首次建立后从不修改,那么就要慎重考虑是不是“过度建模”了。
12.3.4. SEI 3视图
SEI
的Len Bass等专家在《软件架构实践(第2版)》中阐述了“3视图”的观点,他们认为架构设计的工作应该包含3类视图:
- 模块视图 :此处的元素是模块,它们是实现单元。模块表示一种考虑系统的基于代码的方法。模块被分配功能职责区域。这不怎么强调所开发出来的软件如何在运行时表现自己。模块结构能够回答诸如此类的问题:分配给每个模块的主要功能职责是什么?允许模块使用的其他元素是什么?它实际使用的其他软件是什么?什么模块通弄个泛化或特化(继承)关系与其他模块相关?
- 组件-连接器视图 :此处的元素为运行时组件(它们是计算的主要单元)和连接器(它们是组件间通信的工具)。组件-连接器结构回答了诸如此类的问题:we和你们是主要执行组件?它们如何交互?什么是主要的共享数据存储?复制系统的那些不法?数据在系统中经过了哪些地方?系统的哪些部分可以并行运行?在系统执行时,其结构可能会发生怎样的变化?
- 分配视图 :分配结构展示了软件元素和创建并执行软件的一个或多个外部环境中的元素之间的关系。它们回答了诸如此类的问题:每个软件元素在什么处理器上执行?在开发、测试和系统构建期间,每个元素都存储在什么文件中?分配给开发小组的软件元素是什么?
来源:《Software Architecture in Practice》
总的来说,SEI 3视图
方法没有RUP 4+1视图
方法影响大,但也值得架构师研究和体会的。例如:
- 映射视图对实践很有启发。以源码为核心的开发单元要分配给开发人员;而目标单元要和吴磊节点有映射关系,通过安装、部署、烧写等时候藕断完成。
- “架构 = 组件 + 交互”是业界的基本认识,应该在架构的每个视图都有自己关心的“组件”。
12.4. 实践要领
一种优秀的多视图方法,应该能够比较完善的覆盖架构设计的各项哦工作内容,且将每项工作内容明确的、有理有据的、一目了然的规划到不同架构视图中去。
我们来介绍一下5视图方法的怨气,并用两幅画来说明5视图方法的主要思想:落错有致的将众多技术关键点划分成“群落”,“群落”高内聚,“群落”之间松耦合。所以,应用5视图方法,有利于架构师设计思维的“有序”展开。
12.4.1. 缘起:5视图方法的提出
多视图方法是业界广泛认同的一种架构设计思路,具体的多视图方法繁多:
SEI
的3视图方法。涉及视图为:模块视图 、组件-连接器视图 、分配视图 。- 西门子的4视图方法。涉及视图为:概念视图 、模块视图 、代码视图 、执行视图 。
RUP
的4+1视图法。涉及视图为:用例视图 、逻辑视图 、开发视图 、进程视图 、物理视图 。- 联邦企业架构框架(
Federal Enterpriese Architecture Framework
)。涉及视图为:技术架构视图 、信息架构视图 、应用架构视图 、业务架构视图 。 - 其他......
其中,无疑是由Philippe Kruchten于1995年首次提出的4+1视图方法的影响最大。
12.4.2. 总图:每个视图,一个思维角度
《第一财经》栏目有句广告语“有角度就有空间”,想想都觉得颇有道理--作为电视节目,选准了评论的“角度”,也就有了建立观点的“空间”。
而多视图方法背后的核心思想就与此有些类似:从不同角度,规划“分割”与“交互”。
5视图方法包含如下几个视图:
- 逻辑视图
- 开发视图
- 运行视图
- 物理视图
- 数据视图
5个视图各有其“思维立足点”,分别是:
- 职责划分(逻辑视图)
- 程序单元组织(开发视图)
- 控制流组织(运行视图)
- 物理节点安排(物理视图)
- 持久化设计(数据视图)
“思考最大的障碍在于混乱”。抓住每个视图的“思维立足点”。5视图方法就显得“相当清楚”了。
12.4.3. 详图:每个视图,一组技术关键点
接下来,看看架构师最关注的众多技术关注点,如何被5视图梳理的清楚。
例如,Layer
是一种大粒度的“职责划分”单位,Layer
的定义属于逻辑架构视图;而Tier
则属于物理架构视图的考虑范围,它关注与硬件部署。
再例如,对于嵌入式系统而言,有经验的架构师能够从上图中“发现”自己的习惯做法:
- 控制流不仅仅包含进程和线程,中断服务程序也是一种重要的控制流机器(运行架构视图)
- 嵌入式应用数据的持久化常常基于文件(而不是数据库)的概念,最终常写入
Flash
(而不是硬盘)中(数据架构视图) - ......
如果说每个视图都是一个“语言”的话,那么视图内的那些技术关注点就是语言的“词汇”,正是这些不同的技术关注点支撑起不同的思维空间。
最后,看似复杂的5视图方法其实很简单,因为其每个视图都是从特定角度规划系统的分割与交互 ,都是(架构的定义)“组件 + 交互”的一种体现。--原来如此,提炼出了“繁”中之“简”,离成功运用这种方法就不远了!
下一节:有没有一种方法在大产品和小团队之间的缺口上架起一座桥梁呢?答案是肯定的,有!那就是架构。架构最重要的一点,就是它能把难以处理的大问题分解成便于管理的小问题。 -- Eric Brechner,《代码之道》
一流是每个程序设计人员向往并为之奋斗却又无法具体说出的、难以达到的境界,一流的软件非常简明。它灵活而清晰,能通过创造性的机制解决复杂的问题,这些机制语义丰富,可应用于其他可能完全无关的问题,一流意味着寻求恰当的抽象,意味着通过新的途径合理利用有限的资源。 -- Grady Booch,《面向对象项目的解决方案》
划分子系统、定义接口......,这些典型工作都是属于逻辑架构设计的范畴。
接下来,我们主要说说5视图方法中逻辑架构视图的设计:
先从划分子系统的3种必用手段讲起
随后,纠正“我的接口我做主”这种错误认识,代之以“协作决定接口”的正确理解
而且,接下来将解析逻辑架构设计的整体思维套路,解决架构师郁闷已久的“多视图方法只讲做什么、不讲怎么做”的问题
最后,总结逻辑架构设计的10条经验要点。