草稿-读书笔记 - 《软件架构设计》
第一部分 软件架构概念和思想篇
第1章 解析软件架构概念
1.1 软件架构概念的分类
一方面,开发者对架构的明确程度期望甚高;另一方面架构师的架构设计方案却是高来高去;这就造成了大量设计空白,最终往往靠临时拍脑袋或临时商量来决定,于是软件质量下降、协作开发混乱就在所难免了 ---> 深有体会的通病
1.2 软件架构概念大观
组成派(关注软件) vs 决策派(关注人)
1.3 软件架构关注分割与交互
组成派角度:“组件+交互”可以将MVC等“具体架构设计决策”高屋建瓴地表达出来
image.png
1.4 软件架构是一系列有层次性的决策
决策派角度:架构决策是分层次依次展开的(拆解过程由粗入细)
1.5 PM Tool 案例:领会软件架构概念
通过甘特图绘制选择sdk,但是后续可能需要自己绘制或者更换sdk,利用Adapter隔离可能发生的变化为例 --> 决策派和组成派的软件架构概念并不矛盾,只不过是所站的角度不同,且是相辅相成的。
(替换,动态的设计 -> 决策;设计的分层、交互 -> 组成)
总结:我们既应从“架构=组件+交互”的观点中获益,又应运用“架构=重要决策集”的实践经验。
第2章 子系统、框架与架构
2.1 子系统和框架在架构设计中的地位
软件复杂性越来越高,逐渐出现了多个软件系统组成的“超系统”或称“系统的系统”
---> 架构模式就不同了,如SOA和MVC就处在不同的层次上。
所以注意分离之道
接入框架的时候,也应该参与架构,比如加入分层架构(按展现层、业务层、数据层分离框架)。
2.2 子系统与软件架构
为了使软件架构能为软件开发提供足够的指导和限制,软件架构师应当为复杂的子系统设计架构,而不是保持其黑盒子的状态止步不前。
架构的时候经常是多个架构模式组合使用的,比如常见的:
image.png
类 -> 模块 -> 子系统 -> 系统 -> 集成系统
-
子系统如果足够复杂,则也需要架构设计
-
不同的子系统也该按业务采用不同的架构,比如:
- 拓扑子系统:比较复杂,采用领域模型模式 --> 其实我还不明白什么事拓扑子系统(文中举例是网管软件)
- 报表子系统:比较简单,事务脚本模式
- 同个东西,在不同的实践者研制,粒度不同。比如对Android应用层开发来说,TextView是一个很小的原子控件,但是对开发Android系统的人来说,TextView是一个子系统。
- 当进行高一级的架构设计时,子系统就是一个原子单元,一个黑盒
- 当进行子系统本身设计时,他才变成一个结构复杂的黑盒
- 第三方组件一般被看作原子单元
(这点很重要,软件架构师需要根据情况选择去忽略细节)
2.3 框架与软件架构
框架上半成品,软件单元的粒度越大,重用带来的价值量越大,但重用机率越小;反之,粒度越小,重用带来的价值量越小,但重用机率越大。
---> 框架上智慧就在于此,因此,为了追求重用所带来的价值量最大化,要将容易变化的部分封装成扩展点,并辅以回调机制将他们纳入框架的控制范围之内。
框架是软件(注意是半成品,刻意做成的半成品),架构不是软件
---> 引入框架后,架构决策往往会体现在框架之中。但代码不是架构,软件架构上比具体代码高一个层次的概念,代码体现和遵循架构。
框架技术和架构技术,都是为了解决软件系统日益复杂所带来的困难而采取的分治策略 ———— 先大局后局部,就出现了架构;先通用后专用,就出现了框架。
2.4 超越概念:立足实践理解架构
<感觉就是归纳总结:一个复杂系统整体有个架构、子系统有他自己的架构、复合组件有他自己的架构,当然对使用者来说,原子组件没有架构>
2.5 专题:框架技术
框架 vs 类库
简单举例就是,SpringBoot是框架,里面有一堆类库集合,基于框架开发无需知道内部类库组件之间的关系和控制逻辑,非常简单,减少学习成本(基于类库组件则需要)
类比:类库(拼图的最小块) --> 框架(完成了部分的拼图) --> 应用(整块拼图)
<其实IDE就是一个框架>
如何实现框架的扩展点:
- 面向过程的利用函数指针,面向对象的利用抽象方法或者接口,来实现逆向控制
- 还可以通过“数据驱动”来实现控制翻转,比如配置驱动:structs利用structs-config.xml配置文件来降低框架的使用难度。
第3章 软件架构的作用
3.1 充分发挥软件架构的作用
<开头引言的错误守恒定律笑死我了>
产品线的架构设计很难(得非常宏观啊),架构重构比单个架构设计难(因为需要考虑之前架构的好处,尤其是在项目上线后,架构设计面临的限制就更多了)
---> 基于架构维护软件是最简单的
3.2 软件架构对新产品开发的作用
软件架构设计为什么这么难?因为它是跨越现实世界和计算机世界的一座桥。
软件架构需要达到的目的是:
- 上承业务目标
- 下接技术方案
- 控制复杂性:基于问题深度分而治之,简化复杂问题,使得开发人员、管理人员、用户和客户能够理解将要开发的软件系统
- 组织开发:可以进行分模块开发
- 利于迭代开发和增量交付
- 提高质量:"控制复杂性"和"利于增量开发"的衍生优点
3.3 软件架构对软件产品线开发的作用
软件产品线架构特点:将系列产品共用的模块事先实现,供直接重用
---> 更甚至可以以框架的形式予以实现,供定制使用
此时,软件产品线架构就有了一个流行的名字:平台
<产品线架构一定要文档化>
软件产品线架构的作用(当然非常难):
- 固化核心知识
- 提供可重用资产
- 缩短推出产品的周期
- 降低开发和维护总成本
- 提高产品质量
- 支持批量定制
3.4 软件架构对软件维护的作用
维护分为对错误进行修改的“修改性维护”和增加新功能的“增强性维护”
维护过程中,往往涉及架构中的一条“模块协作链”,因此了解架构有利于维护工作;相反,不了解架构而盲目的修改程序可能会违背架构设计的思路,使得整个系统的架构变得混乱,并可能引发出其他意想不到的bug和问题
---> bug改不完,代码越写越臭的原因
3.5 软件架构重构
----> 代码终会越写越臭的,出现以下情况一种时,必须重构:
- 架构太混乱了,以致于进行了一个小改动都会牵动全身
- 将要进行的软件升级力度很大,原先的架构已经不再适应新需求了
重构一般需要经历:逆向工程、重新规划、正向工程 三个步骤
---> 再工程是马蹄铁模型
需要注意的是,逆向工程需要根据源程序、现有文档或知情人访谈等途径了解系统等设计乃至需求也属于逆向工程。只有充分理解原有架构等设计思路,才能权衡利弊。
---> 怪不得离职一定得交接好,保存文档,离职率太高肯定影响开发...
3.6 总结与强调
第二部分 软件架构设计方法与过程篇
第4章 软件架构视图
4.1 呼唤软件架构视图
4.2 软件架构为谁而设计
架构师应内外兼顾,各层并重
4.3 引入软件架构视图
就像一张世界地图,气象学家关注的的是降雨量,社会学家关注人口分布等等。但是一张世界地图很难把不同的信息都绘制上,所以要引入视图,使得更具有专门性。
---> 不同的角色需要看到的软件架构层次不同,关注点不同
多重视图的软件架构不仅仅是架构归档的方式(显而易见),更是架构设计的思维指导(在设计的时候,可以通过架构视图简化,进行分治)
4.4 实践指南:逻辑架构和物理架构
逻辑架构划分了层、子系统、模块等
---> 有了分解必然会产生协作,锁头产生了交互接口与交互机制
<用例技术已经成为捕获功能需求的事实标准,所以逻辑架构的设计往往是从用例分析开始的>
交互机制:方法调用、基于RMI的远程方法调用、发送消息等
---> 所以从宏观角度看android framework的话,注重的是分层、模块和交互,不要太深入细节
物理架构表现了软件系统在计算机运行期间的并发和交互情况
随着分布式系统的流行,“物理层(Tier)”的概念大家已耳熟能详
---> 通过将一个整体的软件系统划分为不同的物理层,可以把它部署到分布在不同位置的多台计算机,从而为远程访问和负载均衡等问题提供了手段。
4.5 设备调试系统案例:领会逻辑架构和物理架构
逻辑架构致力于将软件系统分解成不同的逻辑单元,并规定这些逻辑单元之间的交互接口和交互机制。
物理架构则更重视软件系统运行时的动态结构,以及组成软件系统的目标程序如何部署到硬件上。
第5章 架构设计的5视图法
5.1 架构设计的5视图法
- 逻辑架构(功能需求)
- 开发架构(开发期质量属性:例如可扩展性、可重用性、可移植性、易理解性和易测试性等,偏重于编译期的静态依赖关系)
- 运行架构(运行期间质量属性:偏重于运行时单元的交互问题)
- 物理架构(安装和部署需求:规定部署策略)
- 数据架构(数据需求:数据的传递、复制和同步等策略)
逻辑架构和运行架构都具有动态方面和静态方面。
--> 静在划分,动在交互
5.2 实践中的5视图法
- 多个架构视图之间存在同步问题
比如逻辑架构中的一个逻辑层到了开发视图可能成了几个具体的程序包;物理架构中可能会设计数据的分布和传递备份,这就需要数据架构中定义的结构信息 - 架构视图数量问题:需要根据项目的实际情况增删架构视图
- 同步多视图存在"开销": 业务比较简单的软件,逻辑视图经常和开发视图合二为一
- 安全性非常重要的软件,需要引入单独的安全架构视图,很大程度上是其他视图的汇集,例如会话管理、授权管理来自逻辑视图;采取何种加密来自开发视图;SSL等安全通信协议来自物理视图;消息的校验和转发来自运行视图;对数据库采用的专有安全限制策略来自数据视图
5.3 办公室里的争论:回顾与落实
- 程序员关心的具体类编写和框架选择 --> 开发架构
- 程序经历关系的模块划分和接口定义 --> 逻辑架构
- 系统分析员关心的业务领域对象的关系建模 --> 逻辑架构
- 配置管理员关心的开发出来和编译过后的结构 --> 开发架构
- 数据工程师关心的数据持久化的结构 --> 数据架构
- 部署工程师关心的部署到硬件的策略 --> 物理架构
- 用户关心的子系统划分 --> 逻辑架构
<逻辑架构醉游人关心啊>
5.4 案例:再谈设备调试系统
好的架构设计就体现了怎么满足高性能需求,比如异步、缓冲区、功能划分处理等
用例视图:用例不足以驱动架构设计,因为用例仅是围绕"能为用户带来可观察到结果的"动作序列展开的 --> 提高质量
第6章 从概念性架构到时机架构
实际的软件架构设计过程是,一般先进行概念性架构的设计,把最关键的设计要素和交互机制确定下来,然后再考虑具体技术的运用,设计出实际架构。
6.1 概念性架构
概念性架构没有严格的定义,也不应该有严格的定义
--> 像是从最大的方面,高屋建瓴的给出了”组件+交互“的定义(高层设计决策)。
---> 需要注意的是,不同的概念性架构图,“连接”所代表的含义千差万别:有的是依赖方向,有的是控制方向,有的是数据流向
<隐喻?>
概念性架构具有高度抽象性,所以同属一类的许多软件产品的概念性架构是趋同的。
6.2 实际架构
实际架构非常关心具体技术的运用、具体平台的选择,设计到了可以指导开发的程度。
(概念性架构可能有侧重于5视图的其中一项进行设计,实际架构需要落实5视图)
image.png
6.3 从概念性架构到实际架构
开发人员最关心的点:
- 接口(体现了业务的重要性,不然怎么进行合适的借口设计)
- 子系统(体现了业务的重要性,不然怎么划分合适的粒度)
- 交互机制(所以很多framework解析要提一提是什么交互方式 --> 和性能也很相关)
---> 实际架构中,这三点都得落实
6.4 网络管理系统案例:从分层架构开始
流行的困惑:采用分层架构还是MVC架构?
--> 其实多种架构模式可以联合使用,V、C常在展示层,M常在业务层
<是时候展示真正的技术了>
网管系统必须进行产品线架构才能符合业务情况。
[图片上传失败...(image-1f1ee6-1579141005159)]
如图:
- 上可承丰富多彩的应用:通过抽取API,来实现平台无关
- 下可分离监控部分:通过统一的SPI,达到”隔离变化“的效果,且可单独部署(方便管理和提高性能)
---> 从上有API下有SPI,可以看出需要采用OO技术,面向接口编程
总结:从概念性架构到实际架构,线设计概念性架构,由简入繁,符合人类解决问题的规律。
第7章 如何进行成功的架构设计
7.1 何谓成功的软件架构设计
“适合的才是成功的”
时间紧迫的时候,不能一味的追求软件架构的高质量,除了性能和稳定性等整体质量属性进行综合考虑意外,有个非常重要的一点就是要搭建一个团队协作开发的基础,让不同小组分头对不同的系统模块深入下去,团队并行工作可以大幅缩减项目周期。
--> 快速划分,尽早实现人员上的异步
7.2 探究成功架构设计的关键要素
7.3 指定软件架构设计策略
关键点 | 问题 | 危害 | 策略 | 策略要点 |
---|---|---|---|---|
是否遗漏了至关重要的非功能性需求 | 对需求理解不系统、不全面,对非功能需求不够重视 | 造成返工,项目失败 | 全面认识需求 | 弥补非功能需求的缺失 |
能否驯服数量巨大且频繁变化的需求 | 对于时间和质量的矛盾,办法不足,处理草率 | 耗时不少,质量不高 | 关键需求决定架构 | “需求入架构出”的理解过于简单粗糙,不能适应实践要求 |
能否从容地设计软件架构的不同方面 | 架构设计方案覆盖范围严重不足,许多关键决定被延迟由实现人员仓促决定 | 开发混乱,质量不高 | 多视图探索架构 | 架构是开展系统化团队开发的基础,应当为不同涉众提供指导和限制 |
是否及早验证架构方案并作出了调整 | 假设架构方案是可行的,直到后期才发现问题,造成大规模返工 | 造成返工,项目失败 | 尽早验证架构 | 架构设计方案应解决重大技术风险,并尽早验证架构 |
全面认识需求:
通过需求分类,有助于全面认识需求;众多质量属性需求之间往往会有冲突,如果该情况在当前背景下不会发生,则无需过度设计(会造成资源浪费并增加开发难度)
第8章 软件架构要设计到什么程度
8.1 软件架构要设计到什么程度
不止一个大师级人物表示:采用面向对象方法的“最重要的原因”是它可以帮助我们解决更复杂的问题(而不是更好的可重用性) ---> 怎么理解?
分而治之的两种方式:
- 按问题深度分而治之 --> 例如:实现和接口分离
- 按问题广度分而治之 --> 分层:展现层、业务层、数据层
架构设计和详细设计 --> 可以快速并行深入进行
软件架构为开展系统化的团队开发奠定了基础,让"人尽其才"
架构要涉及到什么程度:
<比如航天航空领域中的软件系统对系统的可靠性要求非常高>
8.2 高来高去式架构设计症状
症状一:缺失重要架构视图
需要架构设计的时候把问题研究清楚,各部分人员拿到架构图就可以很规范的进行工作了
症状二:浅尝辄止、不够深入
架构从全局上规定细节,有助于各部门开发人员统一设计决策,交互的时候更方便。而且深入一些,可以发现公共模块。
症状三:名不副实的分层架构
分层的重点是交互接口和交互机制,只有分层是高来高去的
现实举例:公司组织架构如果只有组织结构,那么来了人物、出了事情就不知道找哪个负责人,就会很乱。
8.3 如何克服高来高去症
高来高去的架构是概念性架构,可用来市场宣传。
8.4 网络管理系统案例:如何将架构设计落实到实处
分层架构中,下层对于上层应尽量做到"黑盒"封装,这样一来,为每一层规划接口就显得非常重要。
第9章 软件架构设计过程
9.1 打造有效的架构设计过程
领域建模:透过问题领域的重重现象,捕捉其背后最为稳固的领域概念及这些概念之间的关系。
---> 项目前期,所建立的领域模型将为所有成员之间和客户之间的交流提供共同认可的语言核心。随着项目的进展,领域模型不断被精化,最终成为整个软件问题的领域层,该层决定了软件系统能力的范围。
9.2 软件架构设计过程解析
软件架构设计过程:
image.png
第10章 需求分析
10.1 需求分析基础
10.2 需求分析在软件过程中所处的位置
10.3 架构师必须掌握的需求知识
10.4 PM Tool 实战:需求分析
第11章 专题:用例技术及应用
11.1 用例图 vs 用力简述 vs 用例规约 vs 用例实现
11.2 储蓄系统案例:需求变化对用例的影响
11.3 用例技术应用指南
11.4 用例与需求捕获
11.5 用例与需求分析
11.6 用例与《软件需求规格说明书》
第12章 领域建模
12.1 领域模型基础知识
12.2 领域建模在软件过程中所处的位置
12.3 领域模型对软件架构的重要作用
12.4 领域模型 vs 文字说明
12.5 PM Tool实战:建立项目管理的领域模型
第13章 确定对软件架构关键的需求
13.1 虚拟高峰论坛:穷兵黩武还是择战而斗
13.2 关键需求决定架构
13.3 确定关键需求在软件过程中所处的位置
13.4 什么是对软件关键的需求
13.5 如何确定对软件架构关键的需求
13.6 PM Tool 实战:确定关键需求
第14章 概念性架构设计
14.1 概念性架构设计的步骤
14.2 鲁棒性分析
14.3 运用架构模式
14.4 PM Tool实战:概念性架构设计
第15章 质量属性分析
15.1 质量属性需求基础
15.2 质量属性分析的位置
15.3 利用"属性--场景--决策"表现架构决策
15.4 PM Tool 实战:可扩展性设计
第16章 细化架构设计
16.1 架构设计细化在软件过程中所处的位置
16.2 设计逻辑架构
16.3 设计开发架构
16.4 设计数据结构
16.5 设计运行结构
16.6 设计物理架构
16.7 注意满足所有约束性软件需求
16.8 PM Tool实战:细化架构设计
第17章 实现并验证软件架构
17.1 基础知识
17.2 总结并验证软件架构的具体做法