第一章
认识软件架构
软件架构的基本定义及其理解
- 软件架构是由结构和功能各异、相互作用的构建集合,按照一定的结构方式构成的系统。它包含系统的基础构成单元,他们之间的作用关系,在构成系统时他们的集成方法及对构成约束的描述等。
- 软件的架构是关于软件系统如何被组织起来的定义,即软件系统是由以下三个要素构成的。
- 组成系统的结构元素或统称为组成系统的构件
- 构件与构件之间的链接以及特定的连接关系
- 系统集成的方法和约束
CMMI模型的基本概念、分级体系、各级的含义等
- CMMI(Capability Maturity Model Integration)即能力成熟度模型集成,是一个过程改进方法,它的目的是帮助组织改进他们的绩效。
- 分级及含义
- 无序:软件过程从外部至完全不可见的,如同是个黑盒,因为被称为时无序的。
- 有管理:软件过程只在若干黑盒的连接点上可见
- 定性:需要开发团队为利益相关者提供更详细、更具体、更准确的过程细节
- 定量:需要达到量化的统计、分析、比较和控制
- 优化:将组织目前所达到的程度,与行业的更高水平进行比较,而达到持续改进的目的
软件架构师和系统分析师的差别
- 在软件开发中的职责和角色,不难发现软件架构师与系统分析师所必需的知识体系也是不尽相同的,系统分析师的主要职责是在需求分析、开发管理、运行维护等方面,而软件架构师的重点工作是在架构与设计这两个关键环节上。因此在系统分析师必须具备的知识体系中对系统的构架与设计等方面知识体系的要求就相对低些;而软件架构师在需求分析、项目管理、运行维护等方面知识的要求也就相对低些。
如何理解软件系统的复杂性
- 软件系统的复杂性=技术的+管理
软件架构的作用
- 软件架构定义了软件计算的组件、局部和总体的构成关系、以及这些组件之间的相互作用
- 除了描述系统的构成和结构关系外,软件构架还表达了系统关键需求与系统构成之间的对应关系,这为系统的设计,提供了分析和评价的依据
第二章
架构与架构师的作用
文件传输架构设计
- 见P23-26,要求对书中的一种技术解决方案能够作清晰的描述。
软件系统的关键质量属性需求:有哪些属性?如何实践?
- 性能、安全性、可用性、易用性、可修改性、可移植性、可测试性、可集成性、可重用性
- 基于关键质量属性需求的架构设计
好的软件架构和差的软件架构的典型特征有哪些?
- 好的软件构架的特征
- 灵活、具有可伸缩性
- 考虑全面并可扩展
- 思路简单明了、直接可以理解
- 结构划分和关系定义清楚
- 模块职责明确和分布合理
- 效益和技术综合平衡
- 差劲的软件构架的特征:往往不是系统不能用(不是功能性问题)而是系统性能问题
- 系统业务处理逻辑缺乏灵活性
- 维护困难
- 功能无法扩展
- 运行速度太慢
- 稳定性差、甚至经常宕机
关键需求影响架构设计
软件产品线的基本定义及其公共性和管理性的定义
- 满足特定市场或用户需求(目标性)有一组公共的、可管理的产品特性(基础性)符合上述两个条件的产品的组合(生产方式)
- 软件产品线的公共性和可管理特性:由一个“公共资源(资产)集”基础上开发的,而不是独立开发、从零开发、随机开发等方式开发的系统
软件产品线管理的三大基本活动
- 核心资源开发
- 基于核心资源的产品开发
- 核心资源和产品开发的技术和管理
第三章
软件架构的描述与可视化
软件架构的五个基本结构及其含义
- 开发架构:反映的是开发期的质量需求
- 物理架构:反映安装和部署需求
- 运行架构:反映的是运行期的质量需求
- 逻辑架构:反映的是功能是如何被分解和协同实现的
- 数据架构:反映的是数据需求
软件架构的五个基本视图及其含义
- 逻辑视图:关注的是系统必须为客户提供的功能
- 开发试图:关注的是程序包
- 进程试图:关注点是运行中的进程、线程、对象等概念,以及相关的并发、同步、通信等问题
- 物理视图:关注的是目标程序及其依赖的运行库和系统软件最终如何安装或部署到物理机器,以及如何部署机器和网络来配合软件系统的可靠性
- 场景视图:作为需求的描述,在某种意义上,是最重要的需求抽象。
掌握UML绘图的基本绘制方法:时序图、包图。
掌握UML的类图的理解
- 能够结合书上p72 图3-15的图,写出类似于书上p255页上的代码。重点掌握关键字:implements、extends、interface等关键字的作用。
第4章
从需求到架构
理解现代软件工程的需求过程:
- 包括需求开发过程及需求管理过程
何为需求管理过程域?
- 需求管理的目的是在客户与开发方之间建立对需求的共同理解,维护需求与其它工作成果的一致性,并控制需求的变更。
- 需求实现是指在系统概要分析、详细分析和系统编码过程中,实现系统的需求。
- 需求跟踪是指通过比较需求文档与后续工作成果之间的对应关系,建立与维护“需求跟踪矩阵”,确保产品依据需求文档进行开发。
- 需求控制是指依据“变更申请-审批-更改-重新确认”的流程处理需求的变更,防止需求变更失去控制而导致项目发生混乱。
需区分析阶段中,架构师应该关注的要点
某个棋类游戏,从需求分析师和架构分析师的角度,分析各自不同的关注点和相同点
UC矩阵概念、原则、主要功能、正确性检验原则
- 概念:是通过一个普通的二维表来分析汇总数据
- 数据守恒原理:数据必定有一个产生的源,而且必定有一个或多个用途
- 主要功能:
- 通过对子通过U/C 矩阵的正确性检验及时发现前段分析和调查工作的疏漏和错误;
- 通过U/C 矩阵的正确性检验分析数据的正确性和完整性;
- 通过对U/C 矩阵的求解过程最终得到子系统的划分,系统之间的联系(“U”)可以确定子系统之间的共享数据。
- U/C 矩阵的分析体现了传统需求分析和系统设计以功能和数据为核心的设计思想
- 正确性检验原则
- 完备性(completeness)检验:指对具体的数据项必须有一个产生者(C)和至少一个使用者(U),功能则必须有产生或使用(U或C)发生。
- 一致性(uniformity)检验:指对具体的数据项必须有且仅有一个产生者(C)。
- 无冗余性(non-verbosity)检验:指 U/C矩阵中不允许有空行和空列。
第五章
软件架构设计的参考模型
OSI模型的启发意义:服务、接口、协议等的启发作用。
- 服务:每一层都为它的上一层提供服务(原语操作),服务定义了这一层应该做什么,而不管上面的层如何访问它以及该层如何实现预定的服务工作
- 接口:接口(原语)告诉自己的上层应该如何访问自己,定义了访问的参数和预期的结果,这也和该层如何实现无关
- 协议:协议是端到端的对等协议(帧格式、信息定义),是该层的内部事物。因此,采用什么协议或协议的改变,是端与端之间的事,与上层(服务)无关
流程处理系统
- 流程处理系统以程序算法和数据结构为中心,象输送或过滤器般处理数据。每一个处理过程中,先接受输入数据,对他们进行处理(过滤),最后产生输出数据。
- 流程处理系统的优点:
- 系统的总体行为,是各个处理部件的简单组合。
- 只要输入和输出数据合适,处理部件可以在不同系统中重复使用。
- 只要增加新的处理部件,系统可以很容易的扩展。
- 系统可以在大规模并行计算机中运行,解决复杂的工程技术和科研难题。
- 流程处理系统的缺点:
- 它主要以一个批量处理的方式则行,不太适合作交互式应用。
- 当有大量和不同形式的输入和输出数据时,数据处理和管理就很伤脑筋。
客户/服务器系统
- 简单的客户机/服务器系统结构中,应分成两部分。
- 客户机负责用户输入和展示,服务器则处理低层的功能,例如数据库的运作等。服务器通常含有一组服务器对象,能同时为多个客户机服务。
- 在客户机/服务器系统中,商业逻辑可由客户机,也可由服务器处理。客户机和服务器之间,通过约定的协议来交互,常见的协议有:http(超文本传输协议), CORBA等。
- 客户机/服务器系统结构的优点:
- 客户机与服务器分离,允许作长距离的连线运作。两者的开发也可以分开同时进行。
- 一个服务器可以服务于多个客户机。
- 客户机/服务器系统结构的缺点:
- 客户机与服务器的通讯依赖于网络,可能成为整体系统运作的瓶颈。(若两者在同一台机子上则没有这个问题)。
- 倘若服务器及其界面定义有改变,则客户机也要做相应改变。当客户机数量很大时,要保证每一个都有最新软件版本,就要费大力气。
第一个缺点的解决方案:最好尽量减少从客户机作的远程调用运算。
第二个缺点的解决方案:可以用“轻便客户机”来解决。另一个办法是应用动态的对象分配或对象传输。
层状系统
- 所谓层,就是一个部件或结点中的一组对象或函数,它们同心协力,提供一定范畴的服务。层状系统则是带有这些分组或层的软件系统,它常见于服务器中,里层给外层提供服务
- 层状系统的优点有:
- 在部件或结点中分设层有助把复杂的问题按功能分解,使整体设计更为清晰。
- 由于内层与外界隔绝,内层函数和服务受到有效的控制,只有界面层的对象作为界面类向外界公开。
- 新的运算可以在界面层引入,它们把内层(核心或持久)的一些运算合起来。
- 如果界面合适,某一个层反复用在不同地方。一个自成一体的层,也可以作为部件或结点使用。
- 层状系统体系结构的缺点有:
- 层的个数多时,系统性能就会下降。因为界面函数可能通过好几层,才能到达某一内层。
- 标准化的层界面可能变得臃肿,降低函数调用的性能。
三级系统
- 三级系统的概念可以推广到多极系统,它是由一连串的客户机/服务器对组成。所以n级系统中,有n-1对客户机/服务器。
- 多级系统的优点:
- 因为系统的功能分布在几个级或服务器上,系统维修和扩展都比较容易。
- 从底层到高层,可以分级控制,对不同级的客户机提供不同水平的服务。
- 方便企业水平的整合。通常的作法是把中间级与企业的其它系统连接起来。
- 多极系统可以扩充,以服务大量同时使用系统的客户机。
- 多级系统的缺点:
- 各对客户机/服务器之间可能有多种不同的通讯协议。
- 由于数据要通过多极结点,而各个结点可能在不同的电脑和操作系统中,调试系统的整体性能就很不容易。
第七章
基于接口、组件和SOA的架构设计和实现
接口的相关概念及应用
- 在C++中,一个类被允许继承多个类。但是在Java、C#等语言中,多继承不被允许。这样,如果想继承多个类时便非常困难。为了实现多重继承,接口就出现了。
- 在一个接口内,允许包含变量、常量等一个类的属性可以包含的基本内容。但是,接口中的方法不允许有具体的代码。和C++里的抽象类中的纯虚函数相同,接口中的方法类似虚函数,接口也就类似于抽象类。这就意味着,接口不能被实例化,不能把程序入口放到接口里。
- 这样设计的目的,使接口专门被用来继承。接口存在的意义也是被继承。不能被实例化。
设计模式的基本概念及要素
- 模式:一种趋于固定的结构方式
- 软件设计模式:是软件设计中总结出来的、广泛应用和成熟的结构和结构关系
- 模式的四个基本要素
- 模式名:pattern name:用一个词来简单表示模式的问题、解决方案和效果。恰当和贴切的模式名,可以使我们对模式的作用“一目了然”
- 问题:Problem:描述应该在何时使用模式,它针对哪些特定的设计问题、问题的前因和后果,以及使用模式的先决条件。
- 解决方案:Solution:是模式本体,模式是如何构成的、它们之间的相互关系和责任。模式是一个问题类的解决方案的抽象模板,因此,它不描述具体的设计或实现,只提供设计问题的抽象思路。
- 效果:Consequences描述模式的应用效果和使用模式应权衡的问题。这是在设计阶段进行设计选择时,不可避免要考虑的问题。
单例模式
- 意图
- 保证一个类仅有一个实例,并提供一个访问它的全局访问点
- 动机
- 有很多环境要求只能有一个实例。例如,系统只能定义一个缺省打印机,如果有2个缺省就不叫缺省了。
- 类负责保存它的唯一实例,保证没有其他实例可以被创建(通过截获创建新实例的请求),并且它可以提供一个访问该实例的方法,这就是单件模式。
- 适用性
- 当类只能有一个实例并且客户从一个众所周知的访问点访问它时(无需选择)
- 当这个唯一的实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时(只有一条通道走到底)
- 结构
Singleton:
1.定义一个Instance操作,允许客户访问它的唯一实例。 Instance是一个类操作,如C++的静态成员函数
2.可以负责创建它自己的唯一实例 - 单例模式参考代码:
class Singleton{ private Singleton(){} private static Singleton singleton ; public static Singleton getInstance(){ if(singleton==null)//1 synchronized(Singleton.class){//2 singleton = new Singleton();//3 } return singleton; } }
Adapter模式
- 意图:
- 将一个类的接口改换成客户希望的另外一个接口,使得原来由于接口不兼容而不能一起工作的那些类可以一起工作。
- 动机:
- 有时,某些被复用的工具仅仅因为接口不匹配而不能被复用
- 适用性:
- 你想使用一个已经存在的类,而它的接口不符合你的需要
- 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(接口可能不兼容)一起工作
- 你想使用一些已经存在的子类,但是不可能对每个都进行子类化以匹配它们的接口。
- 结构1:类适配器
- Client:用户,它希望与Adaptee(包括它的所有子类)协同工作,但接口不兼容,因此,要使用适配器
Target:一个用于定义接口的抽象类,Client通过与符合接口定义的这个抽象类的实例Adapter,实现与Adaptee协同
Adaptee:一个已经存在的类,但接口需要进行适配
Adapter:适配器 - 协同:Client在Adapter实例上调用的操作请求,由适配器调用(转换)Adaptee的操作实现
- 类适配器的实现方法:Adapter是Targat和Adaptee的共同子类,因此,对二者都是匹配的
- 优点:Adapter可以重定义Adaptee的行为,这样可以为Adaptee增加Client需要新的功能
- 缺点:如果Adaptee有很多子类、且可能对Adaptee有重定义,则Adapter要很好地匹配它们是非常困难的(太多了就复杂了)
- 类适配:无法适配adaptee的子类,但是可以重载adaptee的行为
- Client:用户,它希望与Adaptee(包括它的所有子类)协同工作,但接口不兼容,因此,要使用适配器
- 结构2:对象适配器
- 对象适配器的实现方法:Adapter是Adaptee的(或者是它的子类的)对象(适配器是对象而不是子类)
- 优点:允许一个Adapter同时与Adaptee本身或它的多个子类保持一致,Adapter也可以一次性地重定义Adaptee或它的子类的行为,以增加新的功能(与类适配器作用相同)
- 缺点:使得重定义Adaptee的行为比较困难,这就需要生成Adaptee的子类,而Adapter则应引用这个子类而不是Adaptee本身
- 对象适配:可适配adaptee的所有子类,但重定义adaptee困难
- 类适配器与对象适配器的应用选择:选择的重点:重用类的子类的数量和重定义的统一性要求
- 强调个性化:子类很多,用对象适配(子类N:对象N)
- 强调统一性:子类不多,但要求子类的一致性好,用类适配
- Examples