体系结构设计整理.docx

上传人:sccc 文档编号:5135753 上传时间:2023-06-07 格式:DOCX 页数:22 大小:916.55KB
返回 下载 相关 举报
体系结构设计整理.docx_第1页
第1页 / 共22页
体系结构设计整理.docx_第2页
第2页 / 共22页
体系结构设计整理.docx_第3页
第3页 / 共22页
体系结构设计整理.docx_第4页
第4页 / 共22页
体系结构设计整理.docx_第5页
第5页 / 共22页
点击查看更多>>
资源描述

《体系结构设计整理.docx》由会员分享,可在线阅读,更多相关《体系结构设计整理.docx(22页珍藏版)》请在三一办公上搜索。

1、体系结构设计整理一、 名词解释1、 软件体系结构概念(3点)1、 高层结构组成部分:部件(Component)、连接件(Connector)、配置(Configuration)部件聚集了软件运算与状态,连接件聚集了部件之间的关系部件:在软件的体系架构中封装了数据及其处理操作的元素,提供具体应用服务,定义如下: 部件是具有如下特征的架构实体:1) 封装了系统中的功能和/或数据的一个子集2) 通过清晰定义的接口来限制外界对所封装的子集的访问3) 对于被要求执行的上下文有定义明确的依赖关系部件要素:Name、Property、PortCh3 PPT P17连接件:在复杂系统中,交互会比部件范围内的功

2、能实现更重要且更具挑战性,提供独立交互的方法,连接件定义如下:1) 连接件是负责引起和约束部件之间交互的构件2) 它们起到连接作用,但却不是被连接的对象,只是提供连接的规则Ch3 PPT P24 配置:在系统架构中,部件与连接件之间的一个特殊联系的集合,部件与连接件在此特定的组合方式下相互协作完成特定的目标2、 关注点软件体系结构对这些关注点进行权衡的过程起到了交流媒介的作用系统质量属性:可靠性、可修改性、性能、安全性、可测试性、可用性项目环境:1) 开发:人员技术水平、成本、上市时间、资源2) 业务:收益、系统生命周期、市场定位、首次发布日程3) 技术:开发平台、硬件设备、开发工具、模型和标

3、准业务目标3、 设计决策一个系统的体系架构是有关系统的一系列重要设计决策的集合,体系结构也是一系列对系统设计所做的设计决策,包含了重要的“设计决策”,它们说明了软件体系结构得以形成的“理由”,会指导详细设计、实现等后续软件开发工作设计决策的过程:问题-候选设计-理由-解决方案设计决策的重要性:1、 设计决策相互影响,一旦确定便难以改变2、 在确定设计决策过程中,极易违背设计规则和约束3、 之前废弃的决策难以去除、仍然会影响后来的决策2、4+1View即逻辑视图、开发视图、进程视图、部署视图 + 用例视图,前四个为体系结构视图,后一个为需求视图1) 场景视图(Scenarios):定义:关注系统

4、最为重要的需求,描述系统应该实现的场景与用例作用:它们一方面说明软件体系结构设计的出发点,驱动其他4个视图的设计,另一方面用于验证和评估其他4个视图的设计,保证它们的正确性。用例视图位于4+1视图的中心,被其他4个视图环绕描述:可以用UML的用例图进行描述,其重点在于对用力场景的描述2) 逻辑视图Logical view:定义:关注系统的逻辑结构和重要的设计机制,描述系统提供的功能和服务定义:解释系统的逻辑结构和重要的设计机制,其主要内容是软件体系结构的抽象规格,主要关注点是满足用户的各项需求,尤其是功能需求,质量属性需求和约束描述:部件类型用构造型component扩展了的类来描述连接件类型

5、用构造型connector扩展了的类来描述特征用构造性property扩展了的类来描述3) 开发视图Development view: 定义:关注系统的实现结构,描述系统的开发组织描述:利用UML中的构造型process扩展的主动类描述4) 进程视图Process view:定义:关注软件体系结构的运行时表现,描述系统的并发进程组织描述:利用UML中的构造型process扩展的主动类描述5) 部署视图Deployment view:定义:关注系统的基础设施,描述系统的部署于分布描述:使用UML中的部署图描述3、体系结构设计决策一个系统的体系架构是有关系统的一系列重要设计决策的集合定义:设计决策

6、是指决定策略与办法。是对元素、特征和处理的选择,它们涉及一个活多个关注点,直接或间接的影响到软件体系结构。设计决策核心的知识可以分为四个部分:关注点,解决方案,策略和理由。设计决策的重要性:1、 设计决策相互影响,一旦确定便难以改变,常见的设计决策间影响有促进、冲突、禁止、包含、从属、依赖等。2、 在确定设计决策过程中,极易违背设计规则和约束3、 之前废弃的决策难以去除、仍然会影响后来的决策,而且该影响是不可逆的,即很难消除该影响。软件体系结构的设计决策是一个持续的过程,每个决策都要在其前面设计决策的基础上进行,要符合前面设计决策所规定的的设计规则和约束,解决自己的特定问题和关注点。但是所有设

7、计决策都要遵守概念完整性,保证所有设计决策之间相互协调并且与整个系统目标相协调。 4、GRASP模式GRASP,即通用的职责分配软件模式(General Responsibility Assignment Software Patterns)包含以下内容:1) 低耦合:分配职责时保证低耦合,即降低依赖并增加复用性 2) 高内聚:将复杂度控制在可管理范围之内。不可能完全消除时序内聚、过程内聚、通信内聚,必须将这些内聚的 拥有者变成转发者。一个对象仅实现单一的职责,而不实现复杂的职责组合 3) 专家模式:信息的封装。分配职责要看对象所拥有的信息,谁拥有哪方面的信息,谁就负责哪方面的职责,并且一个对

8、象只做这一件事情 4) 创建者模式:如果某个对象与其他对象已经有聚合/包含关系,则这个对象应该由聚合/包含它的对象来创建。这样就不需要依赖第三方,不会增加新的耦合。如果符合下面的一个或多个条件,创建A类的职责将会分配给B类:B类聚合A类的对象B类包含A类的对象B类记录A类对象的实例B类密切使用A类对象B类包含A类初始化所需信息5) 控制者模式:对象协作设计中的一种风格,解决“处理系统事件”这一职责的分配问题。将处理系统时间信息的职责分配个代表其中一个选择的类1. 如果一个程序可以接收外部事件(如GUI事件): 处理模块之间加一个事件管理模块,从而将这二者解耦 :业务或组织、代表整个系统的类、完

9、成业务的活跃对象、虚构类2. 控制者(可以是外观控制者,或者一个纯虚构对象):接受所有的外界请求并转发,很可能形成集中式风格 3. Controller肯定会跟两边对象都有很严重的耦合,并且由于它负责转发很 多信息,所以它的内聚度不高 6) 多态模式:当对象的行为由其类型决定时,需要使用多态的方法调用,而不是通过if/else语句来做选择。 7) 纯虚构模式:为了实现高内聚低耦合,将一组内聚性很高的职责分配给一个完全抽象的类,这个类在问题域中没有任何意义经典场景:分离模型的表示分离模型的实现平台分离复杂行为分离复杂数据结构8) 间接模式:为了防止直接耦合,将职责分配给一个中介对象用于部件与服务

10、之间的交互常见Indirection方法:Pipe/Event/Share Data Styles;Adapter Pattern;Proxy Pattern;Broker Pattern;Delegator Pattern;Mediator Pattern;Publish-Subscribe or Observer pattern9) 保护差异模式:对于将来可能发生的变化,由稳定的接口来承担对象的访问职责二、软件设计的审美标准1、设计的审美标准包括: 1) 简洁性(模块化):结构清晰 2) 结构一致性(概念完整性):3) 坚固性(高质量:易开发、易修改、易复用、易调试、易维护、易理解)2、软

11、件设计方法与技术(至少5点)1) 模块化:进行模块划分,隐藏一些程序片段(数据结构和算法)的实现细节,暴露接口与外界;且保证模块内部的内聚度较高,模块与外界的耦合较低。模块隐藏实现细节,通过接口访问模块,因此促进了简洁性;且因为功能内聚,对外提供统一的外部接口,因此促进了结构一致性2) 信息隐藏:将系统分成模块,每个模块封装一个重要决策,且只有该模块知道实现细节。决策类型可以是需求、变更,不同的决策之间相互独立。信息隐藏和模块化都在一定程度上促进了简洁性,隐藏为了处理一些不需要对外表现的决策段分割,这又在一定程度上牺牲了简洁性而达到了坚固性 3) 运行时注册:针对系统变化,将可能变化的部分与其

12、他部分解耦,不直接发生程序调用,而是在运行时注册。因为这个技术针对可能的变更而使用,本来可 以用一个部件处理的事情,却需要多个部件一同完成,产生了复杂的交互规则,所以牺牲了简洁性,以提高坚固性(灵活性) 4) 配置式编程:针对系统变化,主要解决共性与差异性问题。将可能变化的部分写在一个配置文件中,当要发生变化时,直接修改配置文件。因为需要充分考虑可能的变更来组织配置文件,并且需要在系统启动时对配置文件进行解析,所以牺牲了简洁性,以提高坚固性(灵活性) 5) 设计模式:设计模式牺牲简洁性达到坚固性,保证程序的可维护性和可扩展性。同时在设计模式中是讲究用同样的方法做同样的事,促进了程序结构的一致性

13、6) 体系结构风格:体系结构风格封装了一个设计机制,说明了体系结构中的重要设计决策,并且说明了与此相对应的设计约束。体系结构风格促进了系统的一致性;由于体系结构风格有助于做好系统的高层设计,控制系统复杂度,因此促进了系统的坚固性。7) 职责分配GRASP:促进了坚固性,一致性,有时牺牲简洁性8) 协作设计:促进了坚固性,但有时会牺牲简洁性易理解性,例如Mediator和Controller中会涉及大量复杂交互二、 设计的层次a) 高层设计 1) 出发点:弥补详细设计机制的不足,将一组模块组合起来形成整个系统,进行整体结构设计。同时,体系结构也是一系列对系统设计所做的设计决策 2) 主要关注因素

14、: 项目环境,包括开发环境、业务环境、技术环境;业务目标。为了达成以上目 标,要求体系结构满足简洁性、一致性、坚固性 3) 主要方法与技术: 1. 方法:4+1 view、场景驱动、体系结构风格 2. 技术:模块的表示方法可以是box-line、formal language(ADL,架构描述语言) UML(4+1 view模式使用UML技术实现) 4) 最终制品:体系结构 b) 中层设计1) 出发点:模块与类结构设计;模块划分,做到接口抽象与实现的分离,隐藏实现细节(数据结构和算法),对外提供接口;模块之间尽可能独立,实现单个模块高内聚,模块之间低耦合2) 主要关注因素:简洁性(易开发、易修

15、改、易复用);可观察性“看上去显然是正确的”(易开发,易调试,易维护);高内聚,低耦合;3) 主要方法与技术: 1. 模块化(模块划分+内聚/耦合标准):低耦合(将模块之间的关系最小化)高内聚(将模块之内的各个方法之间的联系最大化) 2. 信息隐藏(模块化+可修改性):一个模块只封装一个secret(主要秘密是需求决策,次要秘密是修改决策)而且只有自己知道决策细节,决策有需求决策、修改决策3. 面向对象:结合模块化和信息隐藏的方式,再加上封装、继承、多态等技术,进行面向对象的设计 4) 最终制品:模块与类结构 c) 低层设计 1) 出发点:将基本的语言单位(类型与语句)组织起来,建立高质量的数

16、据结构和算法(数据结构合理易用,算法可靠、高效、易读)的实现细节2) 主要关注因素:数据结构与算法的简洁性(易读) 3) 主要方法与技术:防御式编程,断言式编程,测试驱动开发,异常处理,配置式编程,表驱动编程,基于状态机编程 4) 最终制品:算法与数据结构,单个的函数三、 体系结构风格1、 描述和比较各种风格1)体系结构风格分为4个levelObject Level:Design PatternsModule Level:Process Level:Physical Unit Level:1、模块级别1、 主程序、子路径风格:部件从其父部件当中得到控制信息,绝不向其同级或上级发出调用信息。部件

17、:过程、功能和模块。连接件:程序调用。约束:控制流总是由顶端延层次结构开始向下传递。优点:处理过程清晰,易理解;能够保证正确性缺点:不利于更改和复用;处理不当会形成公共耦合适用:顺序处理系统;正确性要求较高的系统2、 面向对象式风格:对象能够帮助进行封装内部的secrets,只有通过方法才能够访问对象。部件:对象或模块连接件:方法调用约束:数据的表示对其他对象来说是透明的;每个对象的数据完整性自行维护,每个对象是独立的。优点:只要不修改接口,模块之间的可修改性很好;系统被分解为许多独立的部分缺点:对象之间交互必须了解对方的接口;对象可能产生副作用适用:能够把系统分解为算法+数据的结构,以进行封

18、装3、 分层风格:描述层与层之间的调用结构。部件:过程或对象的集合连接件:过程调用或方法调用约束:系统要被严格组织成层次结构,每一层为其上层提供服务,并调用下一层,不允许跨层调用。优点:基于增加抽象层次设计;易于修改;易用重用缺点:很多系统无法简单的划分层次;必须按层次调用,增加高层和低层实现之间的耦合适用:系统可以按照功能划分为不同的层次4、 隐式调用风格:数据封装,所有调用通过事件完成部件:agent连接件:事件处理约束:抛出事件的部件不了解被影响的部件有哪些;对事件的接收顺序也不能有假设;不能假设事件抛出一定有部件进行处理优点:可重用性好,可修改性好缺点:正确性得不到保障;调试测试会很困

19、难适用:通常适用于能把系统分解为松散耦合的系统5、 管道、过滤器风格:每个Filter都能处理数据然后传递给下一个Filter,Filter可以在任意处处理数据,各个Filter之间无数据共享,通过Pipe交互。部件:Filter连接键:Pipe约束:Filter之间不共享数据;Filter并不了解上下Filter;单个Filter的正确性并不依赖上下的Filter优点:易于理解,支持复用,易于维护和扩展,对于特殊的要求可以满足,支持并发。缺点:不能很好的处理交互问题,传输数据需要额外的空间,可能丢失额外的性能并增加复杂度适用:系统可分解为多个可并行的任务6、 存储库风格:各个客户端读写同一块

20、存储区域部件:一个中心数据结构表示系统状态,一系列独立部件含有在中心数据结构上的操作。连接件:过程调用或直接内存访问约束:所有的agent都是独立的;每个agent都依赖共享数据;agent对数据进行操作。优点:可以充分存储大量数据,空间性能优越;减少复杂数据的复制缺点:必须能够建立稳定的中心数据区;Blackboard可能会成为瓶颈;数据的演化代价很高适用:可以建立一个中心数据区,并且维护复杂的中心信息。7、 MVC风格:Model与Controller、View分离。部件:Model部件用来维护领域信息,通知View的更改;View 部件用来给用户展示信息,发送用户请求到Controlle

21、r;Controller部件用来更改Model状态,对用户请求响应。连接件:系统调用、消息、时间、直接内存访问优点:允许多态,在一个模型中有独立的View;Views能够被序列化;可以任意增加删除View和Controller缺点:增加了复杂度;在View中不能有效获得数据访问;与现代用户界面工具不是特别兼容适用:接口的更改很容易并且可能发生在运行时;用户界面的修改并不会影响逻辑代码2、 进程级别1、 点对点风格:分布式系统中异步消息,可能多个应用程序需要接受同一个消息;发送者和接受者之间的松散耦合的;传输是基于事件接受的;事件存在层级结构部件:发送者、接受者连接件:事件路由SenderRec

22、eiverMessage QueueScheduler3、 物理级别1、 C/S风格部件:Client、Server连接键:基于RPC(远程过程协议)交互协议2、 3层结构风格包括表示层、业务逻辑层和数据层3、 端对端风格部件:部件即作为Client也作为Server连接件:同步异步消息;不共享内存4、 分布式风格网络上所有的物理节点都是平等的,使用时透明。2、对给定场景,判断需要使用的风格 1) Main Program and Subroutine主程序和子程序风格:对正确性要求很高的系统 2) Object-Oriented面向对象风格:数据展示和相关操作被封装在抽象数据类型中 3) L

23、ayered分层风格:能够把程序分成不同的层次,层次之间的协议是稳定的,程序可能只在某一层内部发生修改。比如OSI七层模型,比如UNIX系统 4) Pipe-Filter管道过滤器风格:任务需要独立执行,那么便适用于此风格。比如有顺序的批处理程序、UNIX/Linux命令管道、编译器、信号处理、大数据量处理 5) Implicit Invocation隐式调用风格:通常适用于松散耦合系统,部件之间关联比较少,每一个部件都有它独立的操作,但是会有事件发生需要用到某些操作。 比如调试系统、数据库管理系统、GUI 6) Share Data共享数据风格:大型信息系统,能够将数据做集中处理,并且需要

24、维护一个复杂的中心信息。常见如数据库、专家系统、编程环境。在网络应用中,网络日志使用repository风格,而网络聊天室使用blackboard风格五、详细设计1、职责分配的协作设计1、协作设计(控制风格)的比较和场景判定1) 集中式:将整个系统逻辑集中在某一个controller模块中。controller并不做具体的事情,很容易看出决策,工作流程很容易理解,不过会形成臃肿的Controller,并且Controller难以理解、维护和测试。Controller会把其他模块看作是存储库,这样形成了不必要的耦合,也违反了信息隐藏。不推荐使用 优点:系统容易找到决策点与决策依据缺点:contr

25、oller可能变得过于复杂,难理解、难测试、难维护;controller将其他模块作为知识库,这增加了系统模块间的耦合度,破坏了信息隐藏原则2) 分散式:将整个系统逻辑分散在系统模块中,没有一个集中的controller。虽然分散式控制风格符合面向对象的思想,但是很难看出整体的工作流,因此耦合度高,内聚性低,并且很难隐藏信息。不推荐使用 优点:每一个对象都有很少的行为、维护很少的信息缺点:由于每个对象都可以有控制逻辑,导致整个系统的控制流很复杂,难被理解每个对象都可能需要依赖其他对象才能完成某件事情,导致模块间耦合度高很难做到信息隐藏对象的内聚性也很差其他的一些模块化原则也很难满足3) 委托式

26、:决策制定工作分散在对象网络中,但是会有几个controller做主要决策,每一个controller只绑定少数几个component,支持信息隐藏以及部分的分散。委托式位于完全集中和完全分散之间。推荐使用优点:每个controller一般仅绑定少数几个component,降低模块间耦合度更好地支持信息隐藏系统容易划分层次与模块2、对给定场景和要求的控制风格,根据GRASP模式,判断特定职责的分配低耦合:能不发生系统调用就不发生,委托给别人去调用,比如A、B、C,A调用B,让B调用C去完成其他事情,而不是A再调用C,与C发生耦合高内聚:单一职责才能高内聚,将不相关的行为分给别的类专家模式:谁有

27、信息那个职责就分配给谁创建者模式:对象创建职责分配的问题。A聚合了B的对象;A包含了B的对象;A记录了B对象的引用;A使用了B的对象;在A中包含初始化B对象的数据控制者模式:当有事情发生时,应该由一个controller来做转发这件事,譬如post做enterItem这件事,而不能由GUI与Sale直接耦合,这样Sale也不符合单一职责原则多态:用多态代替ifelse语句。将决定行为的“类型”继承一个公共的接口,譬如CashPayment、CreditPayment、CheckPayment纯虚构模式:虚构出一个问题域中不应该存在的对象来做某些事情,例如数据库模块做save sale这件事,使

28、得sale本身保持高内聚性;常用的纯虚构:表现与模型分离、平台与模型分离、复杂行为分离、复杂数据结构分离间接模式:加中间对象将原本耦合的对象进行解耦。常用的有:Pipe/Event/Share Data Styles、Adapter Pattern、Proxy Pattern、Broker Pattern、Delegator Pattern、Mediator Pattern、Publish-Subscribe or Observer pattern保护差异模式:将可能变化的部分单独封装并维护一个稳定的接口,使得变更时不会对外部造成影响,常用的有:Information Hiding、Data

29、driven (configuration files)、Service lookup (runtime registration)、Interpreter-Driven(generalize module)、Reflective or Meta-Level Designs (Component replace)、Uniform Access (adherence to protocols)、LSP (polymorphism)、Law of Demeter (restrict communication paths)3、根据分析类图和体系结构模块接口,建立基本的设计类图详细设计过程:(1)面

30、向对象/控制风格(委托式)(2)找出概念类以及类重要属性(3)找出行为(4)进行职责分配(5)画详细类图六、设计模式1、课后思考题注:设计模式重点集合类型的封装不完整 (Iterator)层次结构的缺失 (Facade)程序调用的强绑定(运行时注册)问题 (Observer)2、如何针对集合类型,做到Programming to InterfacesProgramming to Interfaces即一个模块在于外部交互时应该严格依赖接口,而不暴露内部实现三种方式:Iterator Pattern、Proxy Pattern、Prototype Pattern(1)Iterator Patte

31、rn:提供了一种方法顺序访问一个聚集对象中的所有元素,同时又不必暴露该对象的内部表示;同时可以支持对聚合对象的多种便利方式;同时为便利不同的聚合结构提供一个统一的接口(即支持多态迭代)。Iterator Pattern类图如下:(2)Proxy Pattern:为其他对象提供一种代理以控制对这个对象的访问,例如对集合对象进行访问时可控制访问的具体方式,而这种访问方式同时保持对客户的透明性,例如IteratorX,IteratorY,IteratorZ是集合对象不同维度上的访问。Proxy Pattern类图如下:(3)Prototype Pattern:3、OCP的手段提示:掌握继承机制,但要

32、了解其他机制所谓OCP即指对扩展开放(当新需求出现的时候,可以通过扩展现有模型达到目的),对修改关闭(对已有的二进制代码,不允许进行修改)。实现OCP原则的关键是抽象与封装。利用抽象封装完成对需求可能发生变更的部分进行处理,具体处理手段如下:(1)使用多态的方式,做一个继承树。此方案针对会发生修改但不是很严重的地方,让需求扩展的实体继承已经存在的实体。(2)使用继承与组合联合的方式。例如:1) Decorator Pattern2) Strategy Pattern3) State Pattern4) Bridge Pattern(3)延迟绑定:运行时注册:使用Event style或Obse

33、rver pattern实现运行时注册的方式,当需要进行扩展时,就让扩展的方法监听某个事件,事件发生时这个方式就会被调用(service lookup)配置文件:使用配置文件进行启动时绑定,将需要修改、扩展的信息写在配置文件中,通过解析配置文件来决定做什么事情(Data Driven)继承多态方式(LSP)构件更替:如果需要修改、扩展,则在加载模块的时候使用修改/扩展的模块,实现加载绑定。一般是将变化的部分写在一个.dll文件中,变化的时候直接更新.dll文件。(Reflective or Meta-Level Design)预定义协议:在两个之间预定义协议,然后各个进程可以独立进行变化,只要

34、通信协议不变。例如TCP/IP等协议(Uniform Access)(4)信息隐藏:(5)泛化模块:Interpreter-Driven(6)限制交互路径(迪米特法则:一个对象应该对其他对象有尽可能少的了解)4、一个模块的信息隐藏有哪两种基本类型,各自有哪些典型的处理手段1、需求:即一个模块的接口功能与模块内部程序细节的分离手段:给出接口,隐藏接口的实现封装设计决策,使得只有本模块知道设计决策的实现方式若有一系列重要决策,则将系列决策均进行封装如果有系列的可能的设计变更,则将这些可能的设计变更进行封装各设计决策之间相互独立使用Facade模式使用Controller2、变化:将要发生变化的程序

35、部分封装起来手段:给出将要修改部分的接口,隐藏接口的实现部分将需求变化封装在各自的类,子程序或者设计单元内Strategy Pattern(仅仅是部分行为或算法实现有变化)、State Pattern(对象的行为因属性的不同而变化)、Bridge Pattern(接口与实现都有差异)5、实现共性与可变性有哪些手段?对给定的场景,给出共性与可变性的设计方案。多态(继承)与聚合其中多态(继承)适合于1 of N的情况,父类中封装共性部分,子类中封装可变性部分聚合适合于M of N的情况,whole角色类封装共性部分,part角色类封装可变性部分(1)多态(继承):1 of N(2)聚合:M of

36、N1、如果一个对象集之间除共性外,有超过个的差异行为,如何处理?Strategy Pattern:两个Strategy类中各有个AlgorithmInterface2、如果一个对象集的部分行为组存在差异性,如何处理?Strategy Pattern:每个Strategy类中有两个AlgorithmInterface3、如果一个对象集的部分属性(以及依赖于这些属性的方法)存在差异性,如何处理?将属性以及方法均抽取出来置于Strategy类中4、如果一个对象集的一个行为需要协作对象来完成,但是它们的协作对象存在差异性,如何处理?将“调用协作对象”这一过程置于Strategy中,Command Pa

37、ttern的变体5、如果一个对象集的行为因为属性的取值而存在差异性,如何处理?State Pattern6、运行时注册的主要机制、适用场景与优缺点1、 Observer Pattern意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新适用场景:(1)当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。(2)当一个对象必须通知其他对象,而他又不能假定其他对象是谁。换言之,你不希望这些对象四紧密耦合的。(3)当一个模型有两个方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中以使它们可以各自独立的改变和复用。(

38、PPT上无)优点:灵活性、可变性、复用性得到保证。目标与观察者之间耦合程度降低,实现抽象耦合,允许独立的改变目标和观察者,可以复用目标对象而无需同时复用其观察者。支持广播通信,目标者不必知道观察者是谁(PPT无)缺点:增加系统复杂程度,对于系统的理解和测试更加困难。一个观察者的无意的更新可能引起其他观察者的意外的更新,也容易引起更更新错误,而这种错误难以捕捉。(PPT无)2、Event Style相比Observer Pattern,可以实现对多个事件的监听。即实现对象间多对多的依赖关系。其他特点同Observer Pattern3、Command Pattern意图:将一个请求封装为一个对象

39、,从而使你可用不同的请求对客户进行参数化;请求排队或记录请求日志,以及支持可撤销的操作。适用场景:(1)抽象出待执行的操作以参数化某对象。(2)在不同的时候制定、排列和执行请求。(3)通过在实施操作之前将状态存储起来以支持撤销操作。(4)支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。优点:将调用操作的对象与知道如何实现该操作的对象解耦。可以将命令存储在栈或队列中以支持请求排队,命令处理模式维护一个历史信息。可以容易的支持undo和redo操作,但是必须存储额外的状态信息以避免滞后影响问题。扩展Command对象很容易。7、对象创建有哪些方法1、简单场景:Creator创建者:对于A、

40、B两个对象,在以下情况下A创建B对象:A聚合了B的对象;A包含了B的对象;A记录了B对象的引用;A使用了B的对象;在A中包含初始化B对象的数据Coupling低耦合:在A聚合、包含、记录、使用B的情况下,如果将创建B对象的职责赋予其他对象,则A需要与其他对象产生多余的耦合Cohesion高内聚:在A中包含初始化B对象的数据的情况下,则A为信息专家,根据高内聚原则,A应当承担B对象创建的职责2、复杂场景:(1)场景一:仅仅一个实例允许被创建使用Singleton Pattern,首先将Constructor私有化;声明一个static private的类实例;创建一个public static的

41、getInstance方法使得外部类可以通过此方法获得此类实例。并且此方法如果用于多线程,要注意声明为protected/synchronize以保证线程安全(2)场景二:实例个数有限制以singleton为基础进行改进(3)场景三:一个类不知道它所必须创建的对象的类;一个类希望有他的子类来制定它所创建的对象;类将创建对象这一职责委托给多个帮助子类中的一个,并且希望将哪一个帮助子类作为代理者这一信息局部化Factory Method(4)场景四:控制子类拓展,子类与父类的算法框架相同,但局部实现方法不同Template Method Pattern(5)场景五:多个需创建的类实例之间存在类型依

42、赖关系Abstract Factory Method(6)场景六:实例的创建和初始化很复杂,例如运行时刻制定要实例化的类;初始化时变量值发生变更Prototype Pattern七、重构1、对指定案例,判断Bad Smell并进行重构1、代码存在冗余:Duplicated Code解决方案:将相同的方法移至父类;(1)同类中有代码重复:将方法提取出来(2)2个相关类的方法:将相同的方法提到父类中实现(3)2个完全不相关的类:构造第三个类,将相同的部分委托于第三个类(或者二者中找出一个来充当第三个类)2、一个类的职责过多:Long Method解决方案:将其分成若干个具有单一职责的类3、一个类(

43、非Controller)包含了太多不相关的东西(对外接口过多):Large Class解决方案:将不必要的接口隐藏起来4、一个类有多个改变的原因,影响了内聚:Divergent Change解决方案将这个类重新划分成若干个小类5、两个方法在逻辑上极其相似:Short Gun解决方案:在其他类中将这个方法集聚起来(可以新建类也可以在已有类中)6、一个类中只有数据(违背了内聚、信息专家原则):Data Class解决方案:封装成Field或者封装成Collection除去Setter将其他类中有关于这个类中属性的方法移到这个类中如果不能移动整个方法,可以提取方法中的一些操作7、一个方法中参数太多解

44、决方案:(1)同时做了太多的任务:将方法划分成几个子方法(2)有许多分散的子部分将参数组合成一个类或者其他的数据结构传入8、一个类对另一个类表现出了过多的关注:Feature Envy解决方案:将一些方法移至数据所在的类中9、多个参数被多个方法同时处理:Data Clumps解决方案:信息隐藏不佳,需要将这几个参数进行封装10、基本型别偏执:Primitive Obssession解决方案:如果满足既有数据又有方法,那么就可以将这些基本类型封装成类11、出现Switch语句:Switch Statements解决方案:用多态来代替条件判断12、平行的继承层次:Parallel Inherita

45、nce Hierarchies解决方案:差异性处理问题,两种差异性组合把其中一个实例指向另一个,用聚合结构代替继承13、懒惰的类:Lazy Class解决方案:这种情况经常在维护中出现把这个类降解到其父类或者拆分成参数14、过度设计:Speculative generality解决方案:避免过度设计,需要拓展的可以通过重构实现15、临时栖息地:Temporary Field解决方案:体现在难以理解的代码,对于判断语句后的非对称方法调用将这些使用没有归宿的参数包括在新提取出来的类中16、消息链:Message chains解决方案:隐藏代理(1)如果调用的是类库,那么一般没有问题(2)如果调用自

46、己的方法,那么就先调用一次将中间值附给中间变量17、中间人:Middle man解决方案:去除中间人,使用集成或者聚合来代替18、不适当的亲密Inappropriate intimacy解决方案:两个类之间共享了太多的信息,耦合很大合理使用getter 和setter重新考虑抽象如果发现他们之间是“真爱”,那么就将其合二为一19、实现相同功能的类具有不同的接口:Alternative classes with different interfaces解决方案:将这两个类合二为一,统一接口20、不完整类库:Incomplete Library Class(1)如果只有少数方法没有实现,引进外来的方法(2)如果有很多方法未实现,在原有基础上继承总而言之,不能直接修改类库21、被拒绝的馈赠(子类与父类中定义的方法想矛盾,子类继承了父类的一些方法,但并不打算使用它):Refused bequest解决方案:(1)将这个方法延后实现(2)用代理来代替继承22、注释不当:Comments解决方案:无固定方案,看着办吧

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号