体系结构设计整理.docx
- 文档编号:29474841
- 上传时间:2023-07-23
- 格式:DOCX
- 页数:32
- 大小:616.11KB
体系结构设计整理.docx
《体系结构设计整理.docx》由会员分享,可在线阅读,更多相关《体系结构设计整理.docx(32页珍藏版)》请在冰豆网上搜索。
体系结构设计整理
体系结构设计整理
一、名词解释
1、软件体系结构概念(3点)
1、高层结构
组成部分:
部件(Component)、连接件(Connector)、配置(Configuration)
部件聚集了软件运算与状态,连接件聚集了部件之间的关系
部件:
在软件的体系架构中封装了数据及其处理操作的元素,提供具体应用服务,定义如下:
部件是具有如下特征的架构实体:
1)封装了系统中的功能和/或数据的一个子集
2)通过清晰定义的接口来限制外界对所封装的子集的访问
3)对于被要求执行的上下文有定义明确的依赖关系
部件要素:
Name、Property、Port
Ch3PPTP17
连接件:
在复杂系统中,交互会比部件范围内的功能实现更重要且更具挑战性,提供独立交互的方法,连接件定义如下:
1)连接件是负责引起和约束部件之间交互的构件
2)它们起到连接作用,但却不是被连接的对象,只是提供连接的规则
Ch3PPTP24
配置:
在系统架构中,部件与连接件之间的一个特殊联系的集合,部件与连接件在此特定的组合方式下相互协作完成特定的目标
2、关注点
软件体系结构对这些关注点进行权衡的过程起到了交流媒介的作用
系统质量属性:
可靠性、可修改性、性能、安全性、可测试性、可用性
项目环境:
1)开发:
人员技术水平、成本、上市时间、资源
2)业务:
收益、系统生命周期、市场定位、首次发布日程
3)技术:
开发平台、硬件设备、开发工具、模型和标准
业务目标
3、设计决策
一个系统的体系架构是有关系统的一系列重要设计决策的集合,体系结构也是一系列对系统设计所做的设计决策,包含了重要的“设计决策”,它们说明了软件体系结构得以形成的“理由”,会指导详细设计、实现等后续软件开发工作
设计决策的过程:
问题->候选设计->理由->解决方案
设计决策的重要性:
1、设计决策相互影响,一旦确定便难以改变
2、在确定设计决策过程中,极易违背设计规则和约束
3、之前废弃的决策难以去除、仍然会影响后来的决策
2、4+1View
即逻辑视图、开发视图、进程视图、部署视图+用例视图,前四个为体系结构视图,后一个为需求视图
1)场景视图(Scenarios):
定义:
关注系统最为重要的需求,描述系统应该实现的场景与用例
作用:
它们一方面说明软件体系结构设计的出发点,驱动其他4个视图的设计,另一方面用于验证和评估其他4个视图的设计,保证它们的正确性。
用例视图位于4+1视图的中心,被其他4个视图环绕
描述:
可以用UML的用例图进行描述,其重点在于对用力场景的描述
2)逻辑视图Logicalview:
定义:
关注系统的逻辑结构和重要的设计机制,描述系统提供的功能和服务
定义:
解释系统的逻辑结构和重要的设计机制,其主要内容是软件体系结构的抽象规格,主要关注点是满足用户的各项需求,尤其是功能需求,质量属性需求和约束
描述:
部件类型用构造型《component》扩展了的类来描述
连接件类型用构造型《connector》扩展了的类来描述
特征用构造性《property》扩展了的类来描述
3)开发视图Developmentview:
定义:
关注系统的实现结构,描述系统的开发组织
描述:
利用UML中的构造型《process》扩展的主动类描述
4)进程视图Processview:
定义:
关注软件体系结构的运行时表现,描述系统的并发进程组织
描述:
利用UML中的构造型《process》扩展的主动类描述
5)部署视图Deploymentview:
定义:
关注系统的基础设施,描述系统的部署于分布
描述:
使用UML中的部署图描述
3、体系结构设计决策
一个系统的体系架构是有关系统的一系列重要设计决策的集合
定义:
设计决策是指决定策略与办法。
是对元素、特征和处理的选择,它们涉及一个活多个关注点,直接或间接的影响到软件体系结构。
设计决策核心的知识可以分为四个部分:
关注点,解决方案,策略和理由。
设计决策的重要性:
1、设计决策相互影响,一旦确定便难以改变,常见的设计决策间影响有促进、冲突、禁止、包含、从属、依赖等。
2、在确定设计决策过程中,极易违背设计规则和约束
3、之前废弃的决策难以去除、仍然会影响后来的决策,而且该影响是不可逆的,即很难消除该影响。
软件体系结构的设计决策是一个持续的过程,每个决策都要在其前面设计决策的基础上进行,要符合前面设计决策所规定的的设计规则和约束,解决自己的特定问题和关注点。
但是所有设计决策都要遵守概念完整性,保证所有设计决策之间相互协调并且与整个系统目标相协调。
4、GRASP模式
GRASP,即通用的职责分配软件模式(GeneralResponsibilityAssignmentSoftwarePatterns)包含以下内容:
1)低耦合:
分配职责时保证低耦合,即降低依赖并增加复用性
2)高内聚:
将复杂度控制在可管理范围之内。
不可能完全消除时序内聚、过程内聚、通信内聚,必须将这些内聚的拥有者变成转发者。
一个对象仅实现单一的职责,而不实现复杂的职责组合
3)专家模式:
信息的封装。
分配职责要看对象所拥有的信息,谁拥有哪方面的信息,谁就负责哪方面的职责,并且一个对象只做这一件事情
4)创建者模式:
如果某个对象与其他对象已经有聚合/包含关系,则这个对象应该由聚合/包含它的对象来创建。
这样就不需要依赖第三方,不会增加新的耦合。
如果符合下面的一个或多个条件,创建A类的职责将会分配给B类:
B类聚合A类的对象
B类包含A类的对象
B类记录A类对象的实例
B类密切使用A类对象
B类包含A类初始化所需信息
5)控制者模式:
对象协作设计中的一种风格,解决“处理系统事件”这一职责的分配问题。
将处理系统时间信息的职责分配个代表其中一个选择的类
1.如果一个程序可以接收外部事件(如GUI事件):
处理模块之间加一个事件管理模块,从而将这二者解耦:
业务或组织、代表整个系统的类、完成业务的活跃对象、虚构类
2.控制者(可以是外观控制者,或者一个纯虚构对象):
接受所有的外界请求并转发,很可能形成集中式风格
3.Controller肯定会跟两边对象都有很严重的耦合,并且由于它负责转发很多信息,所以它的内聚度不高
6)多态模式:
当对象的行为由其类型决定时,需要使用多态的方法调用,而不是通过if/else语句来做选择。
7)纯虚构模式:
为了实现高内聚低耦合,将一组内聚性很高的职责分配给一个完全抽象的类,这个类在问题域中没有任何意义
经典场景:
分离模型的表示
分离模型的实现平台
分离复杂行为
分离复杂数据结构
8)间接模式:
为了防止直接耦合,将职责分配给一个中介对象用于部件与服务之间的交互
常见Indirection方法:
Pipe/Event/ShareDataStyles;
AdapterPattern;
ProxyPattern;
BrokerPattern;
DelegatorPattern;
MediatorPattern;
Publish-SubscribeorObserverpattern
9)保护差异模式:
对于将来可能发生的变化,由稳定的接口来承担对象的访问职责
二、软件设计的审美标准
1、设计的审美标准包括:
1)简洁性(模块化):
结构清晰
2)结构一致性(概念完整性):
3)坚固性(高质量:
易开发、易修改、易复用、易调试、易维护、易理解)
2、软件设计方法与技术(至少5点)
1)模块化:
进行模块划分,隐藏一些程序片段(数据结构和算法)的实现细节,暴露接口与外界;且保证模块内部的内聚度较高,模块与外界的耦合较低。
模块隐藏实现细节,通过接口访问模块,因此促进了简洁性;且因为功能内聚,对外提供统一的外部接口,因此促进了结构一致性
2)信息隐藏:
将系统分成模块,每个模块封装一个重要决策,且只有该模块知道实现细节。
决策类型可以是需求、变更,不同的决策之间相互独立。
信息隐藏和模块化都在一定程度上促进了简洁性,隐藏为了处理一些不需要对外表现的决策段分割,这又在一定程度上牺牲了简洁性而达到了坚固性
3)运行时注册:
针对系统变化,将可能变化的部分与其他部分解耦,不直接发生程序调用,而是在运行时注册。
因为这个技术针对可能的变更而使用,本来可以用一个部件处理的事情,却需要多个部件一同完成,产生了复杂的交互规则,所以牺牲了简洁性,以提高坚固性(灵活性)
4)配置式编程:
针对系统变化,主要解决共性与差异性问题。
将可能变化的部分写在一个配置文件中,当要发生变化时,直接修改配置文件。
因为需要充分考虑可能的变更来组织配置文件,并且需要在系统启动时对配置文件进行解析,所以牺牲了简洁性,以提高坚固性(灵活性)
5)设计模式:
设计模式牺牲简洁性达到坚固性,保证程序的可维护性和可扩展性。
同时在设计模式中是讲究用同样的方法做同样的事,促进了程序结构的一致性
6)体系结构风格:
体系结构风格封装了一个设计机制,说明了体系结构中的重要设计决策,并且说明了与此相对应的设计约束。
体系结构风格促进了系统的一致性;由于体系结构风格有助于做好系统的高层设计,控制系统复杂度,因此促进了系统的坚固性。
7)职责分配GRASP:
促进了坚固性,一致性,有时牺牲简洁性
8)协作设计:
促进了坚固性,但有时会牺牲简洁性易理解性,例如Mediator和Controller中会涉及大量复杂交互
二、
设计的层次
a)高层设计
1)出发点:
弥补详细设计机制的不足,将一组模块组合起来形成整个系统,进行整体结构设计。
同时,体系结构也是一系列对系统设计所做的设计决策
2)主要关注因素:
项目环境,包括开发环境、业务环境、技术环境;业务目标。
为了达成以上目标,要求体系结构满足简洁性、一致性、坚固性
3)主要方法与技术:
1.方法:
4+1view、场景驱动、体系结构风格
2.技术:
模块的表示方法可以是box-line、formallanguage(ADL,架构描述语言)UML(4+1view模式使用UML技术实现)
4)最终制品:
体系结构
b)中层设计
1)出发点:
模块与类结构设计;模块划分,做到接口抽象与实现的分离,隐藏实现细节(数据结构和算法),对外提供接口;模块之间尽可能独立,实现单个模块高内聚,模块之间低耦合
2)主要关注因素:
简洁性(易开发、易修改、易复用);
可观察性“看上去显然是正确的”(易开发,易调试,易维护);
高内聚,低耦合;
3)主要方法与技术:
1.模块化(模块划分+内聚/耦合标准):
低耦合(将模块之间的关系最小化)高内聚(将模块之内的各个方法之间的联系最大化)
2.信息隐藏(模块化+可修改性):
一个模块只封装一个secret(主要秘密是需求决策,次要秘密是修改决策)而且只有自己知道决策细节,决策有需求决策、修改决策
3.面向对象:
结合模块化和信息隐藏的方式,再加上封装、继承、多态等技术,进行面向对象的设计
4)最终制品:
模块与类结构
c)低层设计
1)出发点:
将基本的语言单位(类型与语句)组织起来,建立高质量的数据结构和算法(数据结构合理易用,算法可靠、高效、易读)的实现细节
2)主要关注因素:
数据结构与算法的简洁性(易读)
3)主要方法与技术:
防御式编程,断言式编程,测试驱动开发,异常处理,配置式编程,表驱动编程,基于状态机编程
4)最终制品:
算法与数据结构,单个的函数
三、体系结构风格
1、描述和比较各种风格
1)体系结构风格分为4个level
ObjectLevel:
DesignPatterns
ModuleLevel:
ProcessLevel:
PhysicalUnitLevel:
1、模块级别
1、主程序、子路径风格:
部件从其父部件当中得到控制信息,绝不向其同级或上级发出调用信息。
部件:
过程、功能和模块。
连接件:
程序调用。
约束:
控制流总是由顶端延层次结构开始向下传递。
优点:
处理过程清晰,易理解;能够保证正确性
缺点:
不利于更改和复用;处理不当会形成公共耦合
适用:
顺序处理系统;正确性要求较高的系统
2、面向对象式风格:
对象能够帮助进行封装内部的secrets,只有通过方法才能够访问对象。
部件:
对象或模块
连接件:
方法调用
约束:
数据的表示对其他对象来说是透明的;每个对象的数据完整性自行维护,每个对象是独立的。
优点:
只要不修改接口,模块之间的可修改性很好;系统被分解为许多独立的部分
缺点:
对象之间交互必须了解对方的接口;对象可能产生副作用
适用:
能够把系统分解为算法+数据的结构,以进行封装
3、分层风格:
描述层与层之间的调用结构。
部件:
过程或对象的集合
连接件:
过程调用或方法调用
约束:
系统要被严格组织成层次结构,每一层为其上层提供服务,并调用下一层,不允许跨层调用。
优点:
基于增加抽象层次设计;易于修改;易用重用
缺点:
很多系统无法简单的划分层次;必须按层次调用,增加高层和低层实现之间的耦合
适用:
系统可以按照功能划分为不同的层次
4、隐式调用风格:
数据封装,所有调用通过事件完成
部件:
agent
连接件:
事件处理
约束:
抛出事件的部件不了解被影响的部件有哪些;对事件的接收顺序也不能有假设;不能假设事件抛出一定有部件进行处理
优点:
可重用性好,可修改性好
缺点:
正确性得不到保障;调试测试会很困难
适用:
通常适用于能把系统分解为松散耦合的系统
5、管道、过滤器风格:
每个Filter都能处理数据然后传递给下一个Filter,Filter可以在任意处处理数据,各个Filter之间无数据共享,通过Pipe交互。
部件:
Filter
连接键:
Pipe
约束:
Filter之间不共享数据;Filter并不了解上下Filter;单个Filter的正确性并不依赖上下的Filter
优点:
易于理解,支持复用,易于维护和扩展,对于特殊的要求可以满足,支持并发。
缺点:
不能很好的处理交互问题,传输数据需要额外的空间,可能丢失额外的性能并增加复杂度
适用:
系统可分解为多个可并行的任务
6、存储库风格:
各个客户端读写同一块存储区域
部件:
一个中心数据结构表示系统状态,一系列独立部件含有在中心数据结构上的操作。
连接件:
过程调用或直接内存访问
约束:
所有的agent都是独立的;每个agent都依赖共享数据;agent对数据进行操作。
优点:
可以充分存储大量数据,空间性能优越;减少复杂数据的复制
缺点:
必须能够建立稳定的中心数据区;Blackboard可能会成为瓶颈;数据的演化代价很高
适用:
可以建立一个中心数据区,并且维护复杂的中心信息。
7、MVC风格:
Model与Controller、View分离。
部件:
Model部件用来维护领域信息,通知View的更改;View部件用来给用户展示信息,发送用户请求到Controller;Controller部件用来更改Model状态,对用户请求响应。
连接件:
系统调用、消息、时间、直接内存访问
优点:
允许多态,在一个模型中有独立的View;Views能够被序列化;可以任意增加删除View和Controller
缺点:
增加了复杂度;在View中不能有效获得数据访问;与现代用户界面工具不是特别兼容
适用:
接口的更改很容易并且可能发生在运行时;用户界面的修改并不会影响逻辑代码
2、进程级别
1、点对点风格:
分布式系统中异步消息,可能多个应用程序需要接受同一个消息;发送者和接受者之间的松散耦合的;传输是基于事件接受的;事件存在层级结构
部件:
发送者、接受者
连接件:
事件路由
3、物理级别
1、C/S风格
部件:
Client、Server
连接键:
基于RPC(远程过程协议)交互协议
2、3层结构风格
包括表示层、业务逻辑层和数据层
3、端对端风格
部件:
部件即作为Client也作为Server
连接件:
同步异步消息;不共享内存
4、分布式风格
网络上所有的物理节点都是平等的,使用时透明。
2、对给定场景,判断需要使用的风格
1)MainProgramandSubroutine主程序和子程序风格:
对正确性要求很高的系统
2)Object-Oriented面向对象风格:
数据展示和相关操作被封装在抽象数据类型中
3)Layered分层风格:
能够把程序分成不同的层次,层次之间的协议是稳定的,程序可能只在某一层内部发生修改。
比如OSI七层模型,比如UNIX系统
4)Pipe-Filter管道过滤器风格:
任务需要独立执行,那么便适用于此风格。
比如有顺序的批处理程序、UNIX/Linux命令管道、编译器、信号处理、大数据量处理
5)ImplicitInvocation隐式调用风格:
通常适用于松散耦合系统,部件之间关联比较少,每一个部件都有它独立的操作,但是会有事件发生需要用到某些操作。
比如调试系统、数据库管理系统、GUI
6)ShareData共享数据风格:
大型信息系统,能够将数据做集中处理,并且需要维护一个复杂的中心信息。
常见如数据库、专家系统、编程环境。
在网络应用中,网络日志使用repository风格,而网络聊天室使用blackboard风格
五、详细设计
1、职责分配的协作设计
1、协作设计(控制风格)的比较和场景判定
1)集中式:
将整个系统逻辑集中在某一个controller模块中。
controller并不做具体的事情,很容易看出决策,工作流程很容易理解,不过会形成臃肿的Controller,并且Controller难以理解、维护和测试。
Controller会把其他模块看作是存储库,这样形成了不必要的耦合,也违反了信息隐藏。
不推荐使用
优点:
系统容易找到决策点与决策依据
缺点:
controller可能变得过于复杂,难理解、难测试、难维护;
controller将其他模块作为知识库,这增加了系统模块间的耦合度,破坏了信息隐藏原则
2)分散式:
将整个系统逻辑分散在系统模块中,没有一个集中的controller。
虽然分散式控制风格符合面向对象的思想,但是很难看出整体的工作流,因此耦合度高,内聚性低,并且很难隐藏信息。
不推荐使用
优点:
每一个对象都有很少的行为、维护很少的信息
缺点:
由于每个对象都可以有控制逻辑,导致整个系统的控制流很复杂,难被理解
每个对象都可能需要依赖其他对象才能完成某件事情,导致模块间耦合度高
很难做到信息隐藏
对象的内聚性也很差
其他的一些模块化原则也很难满足
3)委托式:
决策制定工作分散在对象网络中,但是会有几个controller做主要决策,每一个controller只绑定少数几个component,支持信息隐藏以及部分的分散。
委托式位于完全集中和完全分散之间。
推荐使用
优点:
每个controller一般仅绑定少数几个component,降低模块间耦合度
更好地支持信息隐藏
系统容易划分层次与模块
2、对给定场景和要求的控制风格,根据GRASP模式,判断特定职责的分配
低耦合:
能不发生系统调用就不发生,委托给别人去调用,比如A、B、C,A调用B,让B调用C去完成其他事情,而不是A再调用C,与C发生耦合
高内聚:
单一职责才能高内聚,将不相关的行为分给别的类
专家模式:
谁有信息那个职责就分配给谁
创建者模式:
对象创建职责分配的问题。
A聚合了B的对象;A包含了B的对象;A记录了B对象的引用;A使用了B的对象;在A中包含初始化B对象的数据
控制者模式:
当有事情发生时,应该由一个controller来做转发这件事,譬如post做enterItem这件事,而不能由GUI与Sale直接耦合,这样Sale也不符合单一职责原则
多态:
用多态代替if…else语句。
将决定行为的“类型”继承一个公共的接口,譬如CashPayment、CreditPayment、CheckPayment
纯虚构模式:
虚构出一个问题域中不应该存在的对象来做某些事情,例如数据库模块做savesale这件事,使得sale本身保持高内聚性;常用的纯虚构:
表现与模型分离、平台与模型分离、复杂行为分离、复杂数据结构分离
间接模式:
加中间对象将原本耦合的对象进行解耦。
常用的有:
Pipe/Event/ShareDataStyles、AdapterPattern、ProxyPattern、BrokerPattern、DelegatorPattern、MediatorPattern、Publish-SubscribeorObserverpattern
保护差异模式:
将可能变化的部分单独封装并维护一个稳定的接口,使得变更时不会对外部造成影响,常用的有:
InformationHiding、Datadriven(configurationfiles)、Servicelookup(runtimeregistration)、Interpreter-Driven(generalizemodule)、ReflectiveorMeta-LevelDesigns(Componentreplace)、UniformAccess(adherencetoprotocols)、LSP(polymorphism)、LawofDemeter(restrictcommunicationpaths)
3、根据分析类图和体系结构模块接口,建立基本的设计类图
详细设计过程:
(1)面向对象/控制风格(委托式)
(2)找出概念类以及类重要属性
(3)找出行为
(4)进行职责分配
(5)画详细类图
六、设计模式
1、课后思考题
注:
设计模式重点
集合类型的封装不完整(Iterator)
层次结构的缺失(Facade)
程序调用的强绑定(运行时注册)问题(Observer)
2、如何针对集合类型,做到ProgrammingtoInterfaces
ProgrammingtoInterfaces即一个模块在于外部交互时应该严格依赖接口,而不暴露内部实现
三种方式:
IteratorPattern、ProxyPattern、PrototypePattern
(1)IteratorPattern:
提供了一种方法顺序访问一个聚集对象中的所有元素,同时又不必暴露该对象的内部表示;同时可以支持对聚合对象的多种便利方式;同时为便利不同的聚合结构提供一个统一的接口(即支持多态迭代)。
IteratorPattern类图如下:
(2)ProxyPattern:
为其他对象提供一种代理以控制对这个对象的访问,例如对集合对象进行访问时可控制访问的具体方式,而这种访问方式同时保持对客户的透明性,例如IteratorX,IteratorY,IteratorZ是集合对象不同维度上的访问。
ProxyPattern类图如下:
(3)PrototypePattern:
3、OCP的手段[提示:
掌握继承机制,但要了解其他机制]
所谓OCP即指对扩展开放(当新需求出现的时候,可以通过扩展现有模型达到目的),对修改关闭(对已有的二进制代码,不允许进行修改)。
实现OCP原则的关键是抽象与封装。
利用抽象封装完成对需求可能发生变更的部分进行处理,具体处理手段如下
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 体系结构 设计 整理