0. 知识结构
0.1 软件架构设计三大层次
在软件架构设计时,根据抽象程度从高到低可划分为三个层次的模式:**架构模式(Architectural Pattern)、设计模式(Design Pattern)、代码模式(Coding Pattern)**。
- 架构模式是一个系统的高层次策略,涉及到大尺度的组件以及整体性质。
- 设计模式是中等尺度的结构策略。这些中等尺度的结构实现了一些大尺度组件的行为和它们之间的关系。设计模式定义出子系统或组件的微观结构。
- 代码模式(或成例)是特定的范例和与特定语言有关的编程技巧
0.2 框架Framework
软件框架是面向领域(如ERP、计算领域等)的、可复用的“半成品”软件,它实现了该领域的共性部分,并提供了一些定义良好的可变点以保证灵活性和可扩展性。
- 框架是可被应用开发者定制的应用骨架。框架实现了某应用领域通用完备功能(除去特殊应用的部分)的底层服务。
- 框架具体表现为一组抽象类(构件)以及其实例(对象)之间的相互作用方式。框架描述了系统中所有的构件、构件之间的交互、连接件以及如何将构件和连接件结合的规则。
- 软件框架的一个显著特点是逆向控制(Inversion of Control),应用开发人员只要将应用特定的模块绑定到框架内,框架则根据自己的交互机制自动调用该模块,控制由框架负责。
框架可分为三大类:
- 基础设施框架:用于简化系统级软件的开发
- 中间件框架:用于组装分布式应用和构件
- 应用框架:如Web应用框架Eclipse ,Struts等
0.3 框架与软件架构/设计模式对比
0.3.1 框架 与 软件架构
- 框架比架构更具体,更偏重于技术
- 确定框架后,软件体系结构也随之确定
- 对于同一软件体系结构(比如Web开发中的MVC),可以通过多种框架来实现
0.3.2 框架 与 设计模式
- 设计模式是对在某种环境中反复出现的问题以及解决该问题的方案的描述,它比框架更抽象;框架可以用代码表示,也能直接执行或复用,而对模式而言只有实例才能用代码表示
- 设计模式是比框架更小的元素,一个框架中往往含有一个或多个设计模式,框架总是针对某一特定应用领域,但同一模式却可适用于各种应用
- 框架是软件,而设计模式是软件策略
1 软件体系结构
1.1 软件体系结构基本概念
软件体系结构的概念、软件体系结构核心模型及各组成元素的含义
1.1.1 软件体系结构概念
软件系统的体系结构是指根据计算组件和这些组件之间的交互定义系统。
1.2.2 软件体系结构核心模型
软件体系结构基本组成元素:
- 构件Component:系统的逻辑与功能结构组成单元。
- 构件是具有某种功能的可重用的软件模板单元,表示了系统中主要的计算元素和数据存储。
- 构件是一个抽象概念,与具体实现技术无关。
- 原子构件不可再分;复合构件可分解为其他复合构件和原子构件。
- 构件通过其接口与外部环境交互,接口由一组端口 (Port)组成。
- 每个端口表示构件和外部环境的交互作用点。
- 连接件Connector:构件间交互的机制和规则。
- 机制:连接件的具体实现形式
- 规则:构件使用连接件应遵循的规范
- 角色:连接件的交互参与者
- 连接方式分类:单向连接和双向连接、同步/异步连接
- 配置Configuration:表示构件和连接件的拓扑逻辑和约束,包括:
- 构件的端口与连接件的角色之间的关联关系
- 复合构件与其子构件的嵌套包含关系
- 构件Component:系统的逻辑与功能结构组成单元。
1.2 软件体系结构建模
4+1视图概念、关注点、各视图的典型体系结构表示(构件和连接件)
1.2.1 4+1视图概念
“4+1”视图模型从5个不同的视角来描述软件体系结构:逻辑视角、进程视角、开发视角、物理视角和场景视角。
每一个视角只关心系统的一个侧面,5个视角结合在一起反映系统的软件体系结构的完整内容。
Logic View(逻辑视图):基于功能需求抽象,刻画系统的静态结构模型;
Process View(进程视图):刻画系统运行时的结构模型;
Development View(开发视图):考虑开发技术、过程与组织,刻画系统的开发管理结构模型;
Physical View(物理视图):逻辑视图中各功能构件在安装部署环境中的映射,刻画系统的安装部署结构模型;
Scenarios View(场景视图):从系统使用的角度对系统结构的描述。它反映的是在完成某个系统功能时,系统各功能构件间的交互关系。
1.2.2 4+1视图关注点与典型表示
1.2.2.1 逻辑视图
- 逻辑视图主要关注系统的功能需求。
- 在面向对象技术中,可以用对象模型代表逻辑视图,用类图描述逻辑视图。
- 构件:类、类服务、参数化类、类层次(包)
- 连接件:关联、包含聚集、使用、继承、实例化
1.2.2.2 开发视图
- 开发视图关注软件开发环境下实际模块的组织和管理,体现为软件模块、库、子系统和开发单元的结构化组织。
- 开发视图可采用层次结构,每一层为上层提供良好定义的接口,层次越低,通用性越好。
- 构件:模块、子系统、层
- 连接件:参照相关性、模块/过程调用
1.2.2.3 进程视图
- 进程视图侧重系统的运行特性,关注非功能性需求(性能、可用性)。
- 它定义逻辑视图中的各个构件具体在进程/线程中的映射结构。
- 构件:进程、简化进程、循环进程
- 连接件:消息、远程过程调用(RPC)、双向消息、事件广播
1.2.2.4 物理视图
- 物理视图主要考虑如何把软件映射到硬件,它通常要考虑软件系统在计算物理节点与网络拓扑结构上的运行部署等问题。
- 主要关注系统性能、可扩展性、可靠性等软件非功能性需求约束。
- 构件:处理器、计算机、其它设备
- 连接件:通信协议等
1.2.2.5 场景视图
- 场景视图从系统使用的角度对系统结构进行描述。场景反映在完成一个系统功能时,系统各功能构件间的协作关系。
- 场景处于中心位置,它使四个视图有机联系起来,从某种意义上说场景是最重要的需求抽象。
- 场景的表示法:
- 文本、图形表示均可;
- 静态方面用用例图表现,动态方面用活动图、状态图、交互图表现。
1.3 软件体系结构风格
内容范围:管道-过滤器,分层体系结构,基于事件的隐式调用,仓库风格
要点:构件与连接件,实现方式,特点,分类及典型应用
1.3.1 管道-过滤器体系结构风格Pipes-Filters
管道-过滤器体系结构风格为处理数据流的软件系统架构提供了一种参考结构。它是由过滤器和管道组成的。每个处理步骤都被封装在一个过滤器组件中,数据流通过相邻过滤器之间的管道进行传输。每个过滤器可以单独修改,功能单一,并且它们之间的顺序可以进行配置。
构件类型:过滤器(Filter)——数据处理构件
连接件类型:管道(Pipe)——过滤器间的连接件
分类:
- 被动过滤器(下面的一种的方式):
- 过滤器从上一个相邻过滤器采用拉入(pull)方式读取数据。
- 过滤器采用压出(push)方式输出数据给下一个相邻过滤器。
- 主动过滤器:
- 过滤器同时支持以上两种方式(Pull/Push)读写数据。
- 被动过滤器(下面的一种的方式):
特点:
- 功能特性
- 处理或者转换输入数据流
- 对数据流的处理可以容易地分成几个独立的处理步骤
- 非功能特性(质量特性)
- 系统的升级要求可以通过替换/增加/重组过滤器实现,有时甚至由使用者完成操作(系统运行时配置更新)
- 不同的处理步骤不共享信息(过滤器构件间松耦合)
- 功能特性
优点:
- 高内聚和低耦合
- 通过过滤器的增加/移除/重组可实现数据流处理系统的灵活性/可扩展性
- 过滤器构件具有可重用性
- 有利于系统的维护与更新
- 可支持局部步骤的并行处理以提高效率
缺点:
- 增量式处理数据,存在效率问题
- 数据格式转换的问题:数据转换额外开销
- 不适合交互式应用系统
典型系统案例:高级语言编译器系统、Windows CMD/Unix Shell命令解释器系统
1.3.2 基于事件的隐式调用体系结构风格
- 基于事件的(隐式调用风格)系统结构风格中,构件间不采用直接耦合方式交互,而是通过事件机制交互。系统中的事件处理者构件可以通过事件注册来订阅它所关心的事件相关联。当某一事件发生时,系统会通知所有与这个事件相关联的事件处理者构件,即一个事件的激发导致了事件处理者构件与事件源构件间的隐式地交互。
- 构件类型:
- 事件源(Event Source)构件
- 事件处理者(Event Handler)构件
- 事件分发者(Event Dispatcher)构件
- 连接件类型:
- 事件对象(Event)
- 优点:
- 系统具有很好的灵活性,系统易于伸缩扩展
- 缺点:
- 系统控制权的问题,系统放弃了全局控制
- 数据的交互问题,数据可被一个事件传递,但一些情况下,基于事件的系统必须依靠一个共享的仓库进行交互。
- 典型系统案例:图形用户界面系统、某些监控系统、现代高级语言的异常处理
1.3.3 分层体系结构风格
- 实现方式:
- 将系统分成适当层次,按适当次序放置。
- 从最低抽象层次开始,以梯状把抽象层次n放在n-1层顶部。直到功能顶部。
- 第n层提供的绝大多数服务由第n-1层提供的服务组成。
- 每个层次是一个独立的组件。它的责任是提供由上层使用的服务,并且委派任务给下一层次。
- 不允许较高层次直接越级访问较低层次。
- 构件:每一层对应一个构件
- 层构件内部子构件端口保护:为每个层构件指定一个单一的端口(Port)
- 连接件:指定相邻层之间的交互模式,Push mode和Pull model
- 分类:
- Top-Down:用户向顶层N发出一个请求
- Botton-Up:从底层开始的动作连
- 两个彼此交互的层系统
- 特点:
- 优点:
- 层构件的封装性、可重用性、可替换性
- 系统的局部依赖特性
- 缺点:
- 层构件间的依赖性,特别是当低层构件的修改影响高层构件的时
候,可能引起底层之上的多个层构件的修改。 - 效率问题:顶层构件到底层构件之间需要进行层层的参数传递/转
换等。
- 层构件间的依赖性,特别是当低层构件的修改影响高层构件的时
- 优点:
- 典型系统案例:TCP/IP协议系统,Web应用系统(展现层、业务层、数据访问层)
1.3.4 仓库体系结构风格Repository
- 分类:
- 被动仓库:数据库系统
- 主动仓库:黑板系统
- 特点:
- 优点:
- 可扩展性
- 可维护性
- 安全性
- 并行处理性
- 缺点:
- 单一失败点:仓库
- 优点:
- 典型系统案例:专家系统
2 设计模式
2.1 面向对象设计原则
重点是OCP
2.1.1 开闭原则(OCP)(重点)
软件实体应该对扩展开放,但对修改关闭。
设计模式的支持和体现:
Strategy模式;Factory模式;Builder模式;Bridge模式;Façade模式;Mediator模式
2.1.2 里氏代换原则(LSP)
一个软件实体如果使用的是一个基类,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别。
2.1.3 依赖倒转原则(DIP)
要依赖于抽象,不要依赖于具体(依赖倒转)。要针对接口编程,不要针对实现编程。
2.1.4 接口隔离原则(ISP)
使用多个专门的接口比使用单一的总接口要好。(一个类对另一个类的依赖性应当建立在最小的接口之上)。
2.1.5 合成/聚合复用原则(CARP)
要尽量使用合成/聚合,尽量不要使用继承。
2.1.6 迪米特法则(LoD)
一个对象应当对其他对象有尽可能少的了解。
一个软件实体应当与尽可能少的其他实体发生相互作用(直接通信)。
2.2 设计模式的分类及适用的问题(意图)
Factory Method Abstract Factory Prototype Singleton
Adapter(自学理解) Composite Decorator Bridge
Command Observer(了解) Iterator
意图、适用性、实现机制、分类、区别
创建型
2.2.1 Factory Method工厂方法
2.2.2 Abstract Factory抽象工厂
2.2.3 Prototype原型
2.2.4 Singleton单例
结构性
2.2.5 Adapter适配器(自学理解)
2.2.6 Composite组合
- 对于组合模式而言,在安全性和透明性上,会更看重透明性,毕竟组合模式的功能就是要让用户对叶子对象和组合对象的使用具有一致性。而且对于安全性的实现,需要区分是组合对象还是叶子对象,但是有的时候,你需要将对象进行类型转换,却发现类型信息丢失了,只好强行转换,这种类型转换必然是不够安全的。因此在使用组合模式的时候,建议多用透明性的实现方式,而少用安全性的实现方式。
2.2.7 Decorator装饰器
2.2.8 Bridge桥接
行为型
2.2.9 Command命令
2.2.10 Observer观察者(了解)
2.2.11 Iterator迭代器
3 软件应用框架
应用框架中体系结构和设计模式理论的应用(有点迷,不确定)
3.1 Spring框架(3.0)
3.2 Spring框架中用到的设计模式
- beanfactory:简单工厂模式(不属于23种GOF设计模式之一),单例模式
- FactoryBean:工厂方法
- AOP:代理模式,适配器模式,装饰模式,策略模式
- ApplicationListener:观察者模式
- SimpleInstantiationStrategy:策略模式
- JDBCTemplate:模板模式