软件架构与设计 第 2 课 Architectures in Context
架构可以看作是一组关于软件系统的总体设计准则。每个应用都有一个架构,对应一名或多名架构师,并且,架构不是开发的一个阶段。这一讲我们就来了解软件架构放在具体的情境中是什么。
软件架构的上下文包括:
- 需求:新产品是从观察已有的解决方案并了解其局限性中产生的
- 现有的设计和架构提供了解决方案的基本组件
- 我们知道什么是可行的,为什么是可行的,并影响我们的需求
- 现有的经验帮助我们评估可行性,时间与花费
- 需求分析和设计考虑需要同时进行
- 设计
- 实现
- 分析和测试
- 演化
- 开发过程
Non-Functional Properties (NFP) 是架构选择的结果。一个架构框架需要堆 NFP 进行评估,看是否能够支持。
(The Twin Peaks Model)
设计是在整个软件开发过程中都要进行的活动,设计本身也创造了系统的架构。传统的设计阶段会关注以下要素:
- 系统的架构
- 系统的主要组件
- 系统组件之间的交互
而架构本身是一系列主要的设计选择,并不仅仅只是结构。在传统的设计阶段,会把需求『翻译』成算法,这样程序员就可以实现它们,但是在以架构为中心的设计中,注重的以下内容:
- 利益相关人的因素
- COTS 组件
- 首要的风格和结构
- 包和主类结构
- 部署相关问题
- 延后实现/部署问题
在具体的设计中,有一些基本的概念工具:
- 概念分离
- 抽象
- 模块化
由此衍生出的两种比较广泛应用的策略:
- 面向对象设计 Object-Oriented Design OOD
- 主要的抽象是实体
- 封装不同的状态,并提供方法来访问这些状态
- 优势在于可以方便的使用 UML 建模,应用不同的设计模式
- 劣势在于只提供一个层级的封装(对象层级),只提供一种接口的标识,只提供一种显式的连接器(过程调用)。而且有时候会收到语言本身特性的影响,使用共享的地址空间
- 特定领域软件架构 Domain-Specific Software Architectures DSSA
- 从过去的经验中总结出最佳实践
- 新应用可以专注于创新点
- 重用部分的架构和实现
在实现这一步,目标是创造机器可以执行的源代码。这些代码应该符合架构的要求(Faithful Implementation):
- 架构中所有的结构元素都应该在代码中实现
- 源代码中不应该出现架构中没有提到的重要计算元素
- 源代码不应该包含架构中没有体现的联系
这里就有几个问题:这样的要求是否现实?是不是过于严格了?如果偏移了怎么办?
为了解决这些问题,可以采用下面的实现策略:
- 生成技术,例如 parser generator
- 框架:源代码集合,开发人员需要『填空』
- 中间件:CORBA, DCOM, RPC
- 基于重用的技术:COTS, 开源, in-house
- 全部手动实现
上面这些东西怎么凑成一个完整的应用呢,看下图:

这之后就是分析和测试阶段,用来检查制品是否达到质量要求。错误越早被发现,所带来的损失越小。正式的架构模型可以检查其内部一致性与正确性。通过分析我们可以发现:
- 不匹配的组件
- 没有完成的规范
- 不理想的通信模式
- 死锁
- 安全漏洞
通过测试,分发给用户之后就进入了演化和维护阶段。这里需要注意架构腐化与总体质量退化。在以架构为中心的方法中,力求忠实,显式,可维护,可修改的架构模型。
在传统的软件开发过程中,过程本身是焦点所在。而在以架构为中心的软件工程中,产品本身是焦点所在。下面是常见的涡轮机模型

在 时间的横截面:

更复杂一点的话,可能是这样:

截面是这样:

而在项目的最后,截面是这样的:

图示中,体积越大,也就意味着所需要的时间越多。而在开发过程中可以采用以下的过程模型:
- 传统的瀑布流模型
- 以架构为中心的开发
- 基于 DSSA 的项目
- 敏捷开发
- Dysfunctional Process
总结
- 软件架构影响到传统软件开发的每一个环节
- 需求阶段和设计阶段同样重要
- 设计应该借鉴之前的产品开发经验
- 实现过程应该专注于对架构进行忠实的实现,在这个过程中尽可能让每一分钱都用到该用的地方
- 分析和测试可以指引架构
- 产品架构是不断演化的
- 对于过程和产品的关注可以对软件架构有合理的认识
相关文章
- 软件架构与设计 习题课 6 设计模式进阶练习2016-03-30
- 软件架构与设计 习题课 5 设计模式练习2016-03-20
- 软件架构与设计 第 20 课 设计模式2016-03-17
- 软件架构与设计 第 19 课 People, Role, Teams2016-02-27