




已阅读5页,还剩179页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
哈尔滨工业大学计算机学院唐好选Email tanghx 软件设计模式 主要内容 软件设计模式基础创建型模式结构型模式行为型模式 广义讲 软件设计模式是可解决一类软件问题并能重复使用的软件设计方案狭义讲 设计模式是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述 是在类和对象的层次描述的可重复使用的软件设计问题的解决方案模式体现的是程序整体的构思 所以有时候它也会出现在分析或者是概要设计阶段模式的核心思想是通过增加抽象层 把变化部分从那些不变部分里分离出来 什么是设计模式 模式名称 PatternName 问题 Problem 描述应该在何时使用模式 解释了设计问题和问题存在的前因后果 可能还描述模式必须满足的先决条件解决方案 Solution 描述了设计的组成成分 相互关系及各自的职责和协作方式 模式就像一个模板 可应用于多种场合 所以解决方案并不描述一个具体的设计或实现 而是提供设计问题的抽象描述和解决问题所采用的元素组合 类和对象 效果 consequences 描述模式的应用效果及使用模式应权衡的问题 模式的基本要素 模式名和分类意图 设计模式是做什么的 它的基本原理和意图是什么 它解决的是什么样的特定设计问题 动机 说明一个设计问题以及如何用模式中的类 对象来解决该问题的特定情景适用性 什么情况下可以使用该设计模式 该模式可用来改进哪些不良设计 如何识别这些情况 结构 采用对象建模技术对模式中的类进行图形描述 如何描述设计模式 参与者 指设计模式中的类和 或对象以及它们各自的职责协作 模式的参与者如何协作以实现其职责效果 模式如何支持其目标 使用模式的效果和所需做的权衡取舍 系统结构的哪些方面可以独立改变 实现 实现模式时需了解的一些提示 技术要点及应避免的缺陷 以及是否存在某些特定于实现语言的问题代码示例 用来说明怎样实现该模式的代码片段相关模式 与这个模式紧密相关的模式有哪些 其不同之处是什么 这个模式应与哪些其他模式一起使用 描述设计模式 续 开 闭 原则 OpenClosedPrincipal 单一职责原则里氏代换原则依赖倒置原则接口隔离原则 设计模式的原则 设计模式就是实现了上述原则 从而达到代码复用 增加可维护性的目的 定义 软件对扩展是开放的 对修改是关闭的 开发一个软件时 应可以对其进行功能扩展 开放 在进行扩展的时候 不需要对原来的程序进行修改 关闭 好处 在软件可用性上非常灵活 可以在软件完成后对软件进行扩展 加入新的功能 这样 软件就可通过不断的增加新模块满足不断变化的新需求由于不修改软件原来的模块 不用担心软件的稳定性 开闭原则 OCP 实现的主要原则抽象原则 把系统的所有可能的行为抽象成一个底层 由于可从抽象层导出一个或多个具体类来改变系统行为 因此对于可变部分 系统设计对扩展是开放的可变性封装原则 对系统所有可能发生变化的部分进行评估和分类 每一个可变的因素都单独进行封装 开闭原则 OCP 就一个类而言 应该仅有一个引起它变化的原因每一个引起类变化的原因就是一个职责 当类具有多职责时 应把多余职责分离出去 分别创建一些类来完成每一个职责每一个职责都是一个变化的轴线 当需求变化时会反映为类的职责的变化举例interfaceModem publicvoiddial Stringpno publicvoidhangup publicsend charc publiccharrecv Modem类有两个职责 连接管理和数据通信 应将它们分离 单一职责原则 SRP listKov替换原则 LSP 定义 继承必须确保超类所拥有的性质在子类中仍然成立 当一个子类的实例能够替换任何其超类的实例时 它们之间才具有is A关系里氏替换原则是继承复用的基石 只有当派生类可以替换掉其基类 而软件功能不受影响时 基类才能真正被复用 派生类也才能够在基类的基础上增加新的行为LSP本质 在同一个继承体系中的对象应该有共同的行为特征例子 企鹅是鸟吗 生物学 企鹅属于鸟类LSP原则 企鹅不属于鸟类 因为企鹅不会 飞 违反LSP的后果 有可能需要修改客户代码 依赖倒置原则 DIP 定义 高层模块不应依赖低层模块 二者都应该依赖于抽象高层模块只应该包含重要的业务模型和策略选择 低层模块则是不同业务和策略的实现高层抽象不依赖高层和低层模块的具体实现 最多只依赖于低层的抽象低层抽象和实现也只依赖于高层抽象辅助原则任何变量都不应该持有一个指向具体类的引用任何类都不应该从具体类派生任何方法都不应覆盖其任何基类中已经实现了的方法 接口隔离原则 ISP 多个和客户相关的接口要好于一个通用接口如果一个类有几个使用者 与其让这个类载入所有使用者需要使用的所有方法 还不如为每个使用者创建一个特定接口 并让该类分别实现这些接口 在设计模式经典著作 GOF95 中 设计模式从应用的角度被分为三个大的类型创建型模式 结构型模式 行为型模式根据模式的范围分 模式用于类还是用于对象类模式 处理类和子类之间的关系 这些关系通过继承建立 是静态的 在编译时刻便确定下来了对象模式 处理对象间的关系 这些关系在运行时刻是可以变化的 更具动态性从某种意义上来说 几乎所有模式都使用继承机制 所以 类模式 只指那些集中于处理类间关系的模式 而大部分模式都属于对象模式的范畴 设计模式的类型 用来创建对象的模式 抽象了实例化过程工厂模式 父类负责定义创建对象的公共接口 而子类则负责生成具体对象 将类的实例化操作延迟到子类中完成抽象工厂模式 为一个产品族提供统一的创建接口 当需要这个产品族的某一系列的时候 可以从抽象工厂中选出相应的系列创建一个具体的工厂类单件 Singleton 模式 保证一个类有且仅有一个实例 提供一个全局访问点 创建型设计模式 创建型设计模式 生成器 Builder 模式 将复杂对象创建与表示分离 同样的创建过程可创建不同的表示 允许用户通过指定复杂对象类型和内容来创建对象 用户不需要知道对象内部的具体构建细节原型 Prototype 模式 通过 复制 一个已经存在的实例来返回新的实例 不新建实例 被复制的实例就是 原型 这个原型是可定制的 原型模式多用于创建复杂的或者耗时的实例 因为这种情况下 复制一个已经存在的实例使程序运行更高效 或者创建值相等 只是命名不一样的同类数据 结构型模式讨论的是类和对象的结构 它采用继承机制来组合接口或实现 类结构型模式 或者通过组合一些对象来实现新的功能 对象结构型模式 组合 Composite 模式 定义一个接口 使之用于单一对象 也可以应用于多个单一对象组成的对象组装饰 Decorator 模式 给对象动态添加额外的职责 就好像给一个物体加上装饰物 完善其功能代理 Proxy 模式 在软件系统中 有些对象有时候由于跨越网络或者其他障碍 而不能够或者不想直接访问另一个对象 直接访问会给系统带来不必要的复杂性 这时候可以在客户程序和目标对象之间增加一层中间层 让代理对象来代替目标对象打点一切 这就是代理 Proxy 模式 结构型设计模式 结构型设计模式 享元 Flyweight 模式 Flyweight是一个共享对象 它可以同时在不同上下文 Context 使用外观 Facade 模式 外观模式为子系统提供了一个更高层次 更简单的接口 从而降低了子系统的复杂度 使子系统更易于使用和管理 外观承担了子系统中类交互的责任桥梁 Bridge 模式 桥梁模式的用意是将问题的抽象和实现分离开来实现 通过用聚合代替继承来解决子类爆炸性增长的问题适配器 Adapter 模式 将一个类的接口适配成用户所期待的接口 一个适配器允许因为接口不兼容而不能在一起工作的类工作在一起 做法是将类自己的接口包装在一个已存在的类中 着力解决的是类实体之间的通讯关系 希望以面向对象的方式描述一个控制流程模版 Template 模式 定义了一个算法步骤 并允许子类为一个或多个步骤提供实现 子类在不改变算法架构的情况下 可重新定义算法中某些步骤观察者 Observer 模式 定义了对象之间一对多的依赖 当这个对象的状态发生改变的时候 多个对象会接受到通知 有机会做出反馈迭代子 Iterator 模式 提供一种方法顺序访问一个聚合对象中各个元素 而又不需暴露该对象的内部表示 行为型设计模式 责任链 ChainofResponsibility 模式 很多对象由每一个对象对其下一个对象的引用而连接起来形成一条链 请求在这个链上传递 直到链上的某一个对象决定处理此请求 发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求 这使系统可以在不影响客户端的情况下动态的重新组织链和分配责任备忘录 Memento 模式 在不破坏封装性的前提下 捕获一个对象的内部状态 并在该对象之外保存这个状态 这样以后就可将该对象恢复到原先保存的状态命令 Command 模式 将请求及其参数封装成一个对象 作为命令发起者和接收者的中介 可以对这些请求排队或记录请求日志 以及支持可撤销操作 行为型设计模式 状态 State 模式 允许一个 对象 在其内部状态改变的时候改变其行为 即不同的状态 不同的行为访问者 Visitor 模式 表示一个作用于某对象结构中的各元素的操作 可以在不改变各元素的类的前提下定义作用于这些元素的新操作解释器 Interpreter 模式 给定一个语言 定义它的文法的一种表示 并定义一个解释器 这个解释器使用该表示来解释语言中的句子中介者 Mediator 模式 用一个中介对象来封装一系列的对象交互策略 Strategy 模式 定义一组算法 将每个算法都封装起来 并且使它们之间可以互换 策略模式使这些算法在客户端调用它们的时候能够互不影响地变化 行为型设计模式 创建型设计模式 工厂模式抽象工厂模式建造者模式单件模式原型模式 创建型设计模式 在面向对象编程中 常用的方法是用new操作符构造对象实例 但在有些情况下 new操作符直接生成对象会带来一些问题 1 创建对象之前必须清楚所要创建对象的类信息 但个别情况下无法达到此要求 譬如打开一个视频文件需要一个播放器对象 但是用户可能不知道具体播放器叫什么名字 需要系统分派给这个视频文件一个合适的播放器 这种情况下用new运算符并不合适 工厂模式的由来 2 许多类型对象的创造需要一系列步骤需要计算或取得对象的初始设置需要选择生成哪个子对象实例在生成需要对象之前必须先生成一些辅助功能对象在这些情况 新对象的建立就是一个 过程 而不仅仅是一个操作 为了能方便地完成这些复杂的对象创建工作 可引入工厂模式 工厂模式的由来 工厂模式的结构 Product 定义工厂方法所创建对象的接口ConcreteProduct 实现Product接口Factory 声明工厂方法 返回一个Product类型对象 Factory也可以定义一个工厂方法的缺省实现 返回一个缺省ConcreteProduct对象ConcreteFactory 重定义工厂方法 返回一个ConcreteProduct实例 工厂模式的参与者 一个日志管理器 设计日志记录类 支持记录的方法有FileLogEventLog 工厂模式实例分析 LogFactory类publicabstractclassLogFactory publicabstractLogCreate 工厂模式实例分析 FileFactory类publicclassFileFactory LogFactory publicoverrideFileLogCreate returnnewFileLog EventFactory类publicclassEventFactory LogFactory publicoverrideEventLogCreate returnnewEventLog publicclassApp publicstaticvoidMain string args LogFactoryfactory newEventFactory FileFactoryfactory newFileFactory Loglog factory Create log Write 工厂模式客户端程序 客户程序有效避免了具体产品对象和应用程序之间的耦合 增加了具体工厂对象和应用程序之间的耦合在类内部创建对象通常比直接创建对象更灵活工厂模式通过面向对象的手法 将具体对象的创建工作延迟到子类 提供了一种扩展策略 较好的解决了紧耦合问题 工厂模式实例分析 抽象工厂模式的由来 在软件系统中 经常面临 一系列相互依赖对象 的创建工作 由于需求变化 这 一系列相互依赖的对象 也要改变 如何应对这种变化呢 如何像工厂模式一样绕过常规的 new 提供一种 封装机制 来避免客户程序和这种 多系列具体对象创建工作 的紧耦合 一种说法 可以将这些对象一个个通过工厂模式来创建 但是 既然是一系列相互依赖的对象 它们是有联系的 每个对象都这样解决 如何保证他们的联系呢 实例 Windows桌面主题 当更换一个桌面主题的时候 系统的开始按钮 任务栏 菜单栏 工具栏等都变了 而且是一起变的 他们的色调都很一致 类似这样的问题如何解决呢 应用抽象工厂模式 是一种有效的解决途径 抽象工厂模式的由来 抽象工厂模式的意图 意图 提供一个创建一系列相关或相互依赖对象的接口 而无需指定他们具体的类适用场合一个系统独立于其产品创建 组合和表示时一个系统由多个产品系列中的一个来配置时强调一系列相关产品对象的设计以便进行联合时提供一个产品类库 只想显示其接口而非实现时 抽象工厂模式的结构 AbstractFactory 声明创建抽象产品对象的操作接口ConcreteFactory 实现创建具体对象的操作AbstractProduct 为一类产品对象声明一个接口ConcreteProduct 定义一个被具体工厂创建的产品对象 抽象工厂模式的参与者 实例 需要设计一个花园布局花园有三种风格 典雅型 实用型和懒人型花园中有3个位置需要种植植物 花台 墙角和花园中心 抽象工厂模式的应用实例 建造者 Builder 模式的由来 在软件系统中 有时面临着 一个复杂对象 的创建工作 该复杂对象通常由各个部分的子对象用一定的算法构成这个复杂对象的各个部分经常面临着剧烈变化 但是将它们组合在一起的算法却相对稳定如何应对这种变化 如何提供一种 封装机制 来隔离出 复杂对象的各个部分 的变化 从而保持系统中的 稳定构建算法 不随着需求改变而改变 建造者模式的意图和适用性 意图 将一个复杂的构建与其表示相分离 使得同样的构建过程可以创建不同的表示适用性场合需要生成的产品对象有复杂的内部结构创建复杂对象的算法稳定 或建造者模式可以强迫生成一定的顺序当构造过程允许被构造的对象有不同的表示时 建造者模式的结构 建造者模式的参与者 Builder 为创建一个Product对象的各个部件指定抽象接口ConcreteBuilder 实现Builder接口来构造和装配产品各个部件 提供一个检索产品的接口Director 构造一个使用Builder接口的对象Product 表示被构造的复杂对象 实例 设计游戏场景中的房屋房屋由五个部分组成 地板 墙壁 窗户 门和天花板构建房屋的步骤固定 而具体组件 门 窗等 易变采用建造者模式分离易变组件和稳定的构建过程 建造者模式的应用示例 publicabstractclassHouse 定义一个房屋抽象类 publicabstractclassBuilder 这一部分是易变的 publicabstractvoidBuildFloor 地板publicabstractvoidBuildDoor 门publicabstractvoidBuildWindows 窗户publicabstractvoidBuildWall 墙壁publicabstractvoidBuildHouseCeiling 天花板publicabstractHouseGetHouse 建造者模式的应用示例 建造者模式的应用示例 publicabstractclassGameManager publicstaticHouseCreateHouse Builderbuilder builder BuildFloor builder BuildDoor builder Buildwall builder BuildWindows builder BuildHouseCeiling returnbuilder GetHouse 建造者模式的应用示例 publicclassRomanHouseBuilder Builder publicoverridevoidBuildDoor publicoverridevoidBuildFloor publicoverridevoidBuildWindows publicoverridevoidBuildWall publicoverridevoidBuildHouseCeiling publicoverrideHouseGetHouse 建造者模式的应用示例 classApp publicstaticvoidmain Househouse GameManager CreateHouse newRomanHouseBuilder 建造者模式分析 建造者模式的使用使得产品的内部表象可以独立的变化 使用建造者模式可以使客户端不必知道产品内部组成的细节每一个Builder都相对独立 而与其它Builder无关可对构造过程更加精细控制将构建代码和表示代码分开建造者模式的缺点在于难于应付 分步骤构建算法 的需求变动 单件 Singleton 模式的由来 单件模式的实例较为普遍 系统中只能有一个窗口管理器系统中只能有一个文件系统一个数字滤波器只能有一个A D转换器一个会计系统只能专用于一个公司 单件模式的由来 如何才能保证一个类只有一个实例并且这个实例易于被访问呢 一个全局变量使得一个对象可以被访问 但它不能防止你实例化多个对象一个更好的办法是 让类自身负责保存它的唯一实例 这个类可以保证没有其他实例可以被创建 并且它可以提供一个访问该实例的方法 单件模式的意图和适用性 意图 保证一个类仅有一个实例 并提供一个全局访问点适用场合 当类只能有一个实例而且用户可以从一个众所周知的访问点访问它时当这个唯一实例是通过子类化可扩展的 并且客户应该无需更改代码就能使用一个扩展实例时 单件模式的结构 Singleton被调用的单件对象定义一个Instance操作 允许客户访问它的唯一实例 Instance是一个类操作 一个静态成员函数 可能负责创建它自己的唯一实例 单件模式的应用示例 ClassSingleton 单件模式的定义public staticSingleton Instance 通过该成员函数访问单件protected Singleton 构造函数为受保护型 直接实例化将出错private staticSingleton instance 指向本身唯一实例的指针 单件模式的应用示例 Singleton Singleton instance 0 初始化类成员Singleton Singleton Instance If instance 0 instance newSingleton 如果成员变量为0 则唯 一实例化 return instance 单件模式的效果分析 对唯一实例的受控访问 因为Singleton类封装唯一实例 所以它可以严格的控制客户怎样以及何时访问它缩小名空间 Singleton模式是对全局变量的一种改进 它避免了那些存储唯一实例的全局变量污染名空间允许对操作和表示的精化 Singleton类可以有子类 而且用这个扩展类的实例来配置一个应用是很容易的 可以用所需要的类的实例在运行时刻配置应用 原型 Prototype 模式的由来 在软件系统中 客户希望创建一个类对象 产品 时 可能有三种情况 知道产品具体型号 使用new运算符创建 不知道型号 知道特定的需求 使用工厂模式 不知道需求 但想要一个和已知对象相同的对象 使用原型模式 原型 Prototype 模式的意图和适用性 意图 用原型实例指定创建对象的种类 并且通过拷贝这些原型创建新的对象适用性 在下列情况下 应当使用Prototype模式当一个系统应独立于其产品创建 构成和表示时当要实例化的类在运行时刻指定时为了避免创建一个与产品类层次平行的工厂类层次时 原型模式的结构 客户 客户端类向原型管理器提出创建对象请求抽象原型 它是对各种具体原型的抽象 通常由一个接口或抽象类实现具体原型 被复制的对象 此角色需要实现抽象的原型角色所要求的接口原型管理器 创建具体原型类的对象 记录每一个被创建的对象 原型模式的参与者 开发一个调色板 用户单击调色板上任一个方块 将会返回一个对应的颜色的实例很自然 我们利用OO的思想 把每一种颜色作为一个对象 并为他们抽象出一个公用的父类 原型模式应用示例 使用原型模式开发调色板的结构图 原型模式应用示例 Prototype模式的优点 1 对客户隐藏具体产品类 减少了客户知道的名字的数目 2 允许客户只通过注册原型实例就可以将一个具体产品类并入系统中 客户可以在运行时刻建立和删除原型 3 具有给一个应用软件动态加载新功能的能力 由于其独立性较高 可以很容易动态加载新功能而不影响老系统 4 产品类不需要非得有任何事先确定的等级结构 适用于任何的等级结构Prototype模式的缺点 Prototype模式的最主要缺点就是每个类必须配备一个克隆方法 原型模式的应用效果分析 工厂模式是一种极端情况下的抽象工厂模式 而抽象工厂模式可以看成是工厂模式的一种推广工厂模式的特点一个抽象产品类 可以派生出多个具体产品类一个抽象工厂类 可以派生出多个具体工厂类每个具体工厂类只能创建一个具体的长品类实例抽象工厂模式的特点多个抽象产品类 每个抽象产品类可以派生出多个具体产品类一个抽象工厂类 可以派生出多个具体工厂类每个具体工厂类可以创建多个具体产品类的实例 抽象工厂模式与工厂模式的区别 提供一个接口 用于创建相关和依赖对象的家族 而不需要明确指定具体类 抽象工厂允许客户使用抽象接口来创建一组相关产品 而不需要关心具体实际产出的产品是什么总结所有工厂都是用来封装对象的创建简单工厂 可以把客户程序从具体类解耦工厂方法使用继承 把对象创建委托给子类 子类实现工厂方法来创建对象抽象工厂使用对象组合 对象的创建被实现在工厂接口所暴露出来的方法中所有工厂模式都是通过减少应用程序与具体类之间的依赖关系促进松耦合工厂方法允许类将实例化延迟到子类进行抽象工厂创建相关的家族 而不需要依赖他们的具体类工厂帮助我们针对抽象编程 而不是针对具体类编程 抽象工厂模式与工厂模式的区别 工厂模式 定义一个创建对象的接口 由子类决定要实例化的具体类 工厂方法让类把实例化推迟到子类抽象工厂模式 提供一个接口 用于创建相关或依赖对象的家族 而不需要明确指定具体类建造者模式 封装一个产品 复杂对象 的构造过程 并允许按照步骤构造 向客户隐藏了产品的内部表现单件模式 确保一个类只有一个实例 并提供全局访问点原型模式 当创建给定类实例的过程很昂贵或很复杂时 使用原型模式 向客户隐藏制造新实例的复杂性 创建型设计模式总结 结构型设计模式 适配器模式外观模式装饰模式桥接模式享元模式代理模式组合模式 结构型模式的主要内容 适配器模式的由来 一个team要为外界提供S类服务 但team里面没有能够完成此项任务的member 只有team外的A可以完成这项服务 为保证对外服务类别的一致性 提供S服务 将A招安到team内 负责提供S类服务A不准备接受招安 可安排B去完成这项任务 并让B做好A的工作 让B工作的时候向A请教 此时 B是一个复合体 提供S服务 是A的继承弟子 将一个类的接口 转换成客户期望的另一个接口 适配器让原本接口不兼容的类可以一起工作 适配器模式使用过程 客户通过目标接口调用适配器的方法对适配器发出请求适配器使用被适配者接口把请求转换成被适配者的一个或者多个调用接口客户接收到调用的结果 但并未察觉这一切是适配器在起转换作用 适配器模式的意图和适用性 意图 将一个类的接口转换成客户希望的另外一个接口 使得原本由于接口不兼容而不能一起工作的类可以一起工作适用场合 使用一个已经存在的类 而它的接口不符合要求创建一个可以复用的类 该类可以与其他不相关的类或不可预见的类 即那些接口可能不一定兼容的类 协同工作使用一些已经存在的子类 但不可能通过子类化以匹配各自接口 对象适配器可以适配它的父类接口适配器模式分为类适配器和对象适配器 类适配器 用一个具体的Adapter类对Adaptee和Target进行匹配 Adapter类多重继承Adaptee和Target类Adapter可重定义Adaptee的部分行为 因为Adapter是Adaptee的一个子类 类适配器模式示例 Target 定义Client使用的与特定领域相关的接口publicinterfaceTarget voidrequest Adaptee 现在需要适配的已经存在的接口publicclassAdaptee publicvoidspecificRequest Adapter 对Adaptee的接口与Target接口进行适配publicclassAdapterextendsAdapteeimplementsTarget publicvoidrequest super specificRequest 对象适配器 允许一个Adapter与多个Adaptee同时工作 即Adaptee本身以及它的所有子类 如果有子类的话 同时工作 Adapter可以一次给所有的Adaptee添加功能使用组合 不仅可以适配某个类 也可以适配该类的任何子类 对象适配器模式示例 Target 定义Client使用的与特定领域相关的接口publicinterfaceTarget voidrequest Adaptee 现在需要适配的已经存在的接口publicclassAdaptee publicvoidspecificRequest Adapter 对Adaptee的接口与Target接口进行适配publicclassAdapterimplementsTarget publicAdapter Adapteeadaptee super this adaptee adaptee publicvoidrequest adaptee specificRequest privateAdapteeadaptee 适配器模式效果分析 优点方便设计者自由定义接口 不用担心匹配问题缺点属于静态结构 由于只能单继承 所以不适用于多种不同的源适配到同一个目标 外观 Facade 模式的由来 毕业生 教务处 公安处 后勤处 图书馆 饭卡 饭卡余额 借书证 借书证押金 身份证 学生证 派遣证 学生证 毕业证 学位证 外观 Facade 模式的由来 毕业生 毕业手续代办处 教务处 后勤处 图书馆 公安处 学生证身份证借书证饭卡 毕业证学位证派遣证饭卡余额借书证押金 外观 Facade 模式的由来 外观 Facade 模式的意图和适用性 提供了一个统一的接口 用来访问子系统中的一群接口 外观定义了一个高层接口 让子系统更容易使用解除客户程序与抽象类具体实现部分的依赖性 有利于移植和更改当需要构建层次结构的子系统时 使用Fa ade模式定义每层的入口点 如果子系统间相互依赖 他们只需通过Fa ade进行通讯外观模式的本质是让接口变得更简单 外观 Facade 模式的结构 外观 Facade 模式的参与者 Fa ade知道哪些子系统类负责处理请求将客户的请求代理给适当的子系统对象SubsystemClasses实现子系统的功能处理由Fa ade对象指派的任务没有Fa ade的任何相关信息 外观 Facade 模式的效果分析 对客户端屏蔽子系统组件 减少客户端使用对象数目实现了子系统与客户之间松耦合的关系 使得子系统组件的变化不会影响到客户不限制客户应用子系统类 装饰 Decorator 模式的由来 动态给对象添加额外职责 比如 一幅画有没有画框都可以挂在墙上 画是被装饰者 在挂在墙上之前 画可以被蒙上玻璃 装到框子里 玻璃画框就是装饰不改变接口 但加入责任 Decorator提供了一种给类增加职责的方法 不是通过继承 而是通过组合实现的 装饰 Decorator 模式的意图和适用性 意图动态地给一个对象添加一些额外的职责 就增加功能来说 Decorator模式比生成子类更为灵活适用场合在不影响其他对象的情况下 以动态 透明的方式给单个对象添加职责当不能采用生成子类的方法进行扩充时 一种情况是 可能有大量独立扩展 每一种组合将产生大量的子类 使得子类数目呈爆炸性增长 另一种情况是因为类定义被隐藏 或类定义不能用于生成子类 装饰 Decorator 模式的结构 Component对象接口 可以给对象动态地添加职责ConcreteComponent具体对象Decorator维持一个指向Component对象的指针 并定义一个与Component接口一致的接口ConcreteDecorator向组件添加职责Decorator将请求转发给它的Component对象 并有可能在转发请求前后执行一些附加的动作 装饰 Decorator 模式的结构 装饰 Decorator 模式的评价 使用Decorator模式可以很容易地向对象添加职责 可以用添加和分离的方法 在运行时添加和删除职责使用Decorator模式可以很容易地重复添加一个特性 而两次继承则极容易出错避免在层次结构高层的类有太多的特征 可以从简单的部件组合出复杂的功能 具有低依赖性和低复杂性缺点 Decorator与Component不一样 使用装饰时不应该依赖对象标识 有许多小对象 桥接 Bridge 模式的由来 例子 相同模块的跨平台使用设计模块A和B希望模块A和B能应用在X操作系统上 让A和B继承X操作系统的接口希望模块A和B能应用在Y操作系统上 让A和B继承Y操作系统的接口 以此类推 问题 模块A和B缺乏复用性解决 抽象出统一的操作系统类的接口连接模块A和B的平台无关接口 通过桥接两个抽象模块来消除模块间的继承耦合 提高复用性 扩展Window抽象使之用于不同种类的窗口或新的平台很不方便 继承机制使得客户代码与平台相关 桥接 Bridge 模式的由来 将Window抽象和它的实现部分分别放在独立的类层次结构中 针对窗口接口 针对平台的窗口实现 桥接 Bridge 模式的由来 桥接 Bridge 模式的意图和适用性 意图 桥接模式的作用就是将抽象部分与实现部分分离 使它可以独立的变化适用的情况不希望在抽象和它的实现部分之间有一个固定的绑定关系想对客户完全隐藏抽象的实现部分 桥接 Bridge 模式的结构 桥接 Bridge 模式的参与者 Abstraction定义抽象类的接口维护一个指向Implementor类型对象的指针RefinedAbstraction扩充由Abstraction定义的接口Implementor定义实现类的接口 不一定要与Abstraction的接口完全一致 甚至可以完全不同ConcreteImplementor实现Implementor接口并定义它的具体实现Abstraction将Client的请求转发给它的Implementor对象 桥接 Bridge 模式的效果分析 分离接口及其实现部分 抽象类的实现可以在运行时刻进行配置 一个对象甚至可以在运行时刻改变它的实现提高可扩充性 抽象与实现两部分可以单独扩充实现细节对客户透明 可以对客户隐藏实现细节 桥接 Bridge 模式的意义 脱耦是指将抽象和实现之间的耦合解脱开 或者说将他们之间的强关联改成若关联强关联是指在编译时期已经确定的 无法在运行时期动态改变的关联弱关联是可以动态确定并可在运行时刻动态改变的关联继承关系是强关联 聚合关系是弱关联 将两个角色之间的继承关系修改为聚合关系 就是将他们之间的强关联变换成弱关联 桥模式中的所谓脱耦就是指在一个软件系统的抽象和实现之间使用组合 聚合关系而不是继承关系 从而可以使两者可以相对独立的变化 享元 Flyweght 模式的由来 当大量使用同一种类型的实例 每个实例中包含部分相同的数据 可能极大的耗费资源 使用Flyweight模式可以提高内存效率以CD唱片为例 每个CD有三个字段 出片日期 歌唱者姓名 唱片曲目姓名可能重复 可能有同一个演唱者的多个不同时期不同曲目的CD 歌唱者姓名可共享 其他字段均不可共享当你有几千张甚至更多CD时 Flyweight模式将节省更多空间 共享的flyweight越多 空间节省也就越大 享元 Flyweght 模式的意图和适用性 意图 避免大量拥有相同内容的小类的开销 使大家共享一个类 元类 适用性一个应用程序使用了大量的对象冗余使用了大量的对象 造成了很大的存储开销 享元 Flyweght 模式的结构 享元 Flyweght 模式的参与者 Flyweight 描述一个接口 可接受并作用于外部状态ConcreteFlyweight 实现Flyweight接口 并为内部状态增加存储空间 必须是可共享的 存储的状态必须是内部的UnsharedConcreteFlyweight 不强制共享FlyweightFactory 创建并管理flyweight对象 确保合理地共享flyweight 提供已创建的flyweight实例或者创建一个 如果不存在的话 Client 维持一个对flyweight的引用 计算或存储一个 多个 flyweight的外部状态 享元 Flyweght 模式的参与者 Flyweight执行时所需的状态必定是内部或外部的 内部状态存储在ConcreteFlyweight中 外部对象则由Client对象存储或计算 当用户调用flyweight对象操作时 将该状态传递给它用户不应直接对ConcreteFlyweight类进行实例化 而只能从FlyweightFactory对象得到ConcreteFlyweight对象 以保证对它们适当地进行共享 享元 Flyweght 模式的效果分析 Flyweight模式的核心就是把大量共享的对象收集在一起使用简单工厂模式进行管理 避免由于大量的小对象导致系统的内存过渡消耗当重复对象较多时 Flyweight模式具有较好的空间性能 但在查找搜索上消耗了时间复杂度 代理 Proxy 模式的由来 某个客户端不能直接操作到某个对象 但又必须和那个对象有所互动如果对象是一个大图片 需要花费很长时间才能显示出来 此时需要做个图片Proxy来代替真正的图片如果对象在某远端服务器上 直接操作这个对象因为网络速度原因可能比较慢 那我们可以先用Proxy来代替那个对象如何应对这种变化 如何提供一种机制让原本交互起来比较困难的两个对象实现畅通无阻地交流呢 如何保持系统的结构不随着需求改变而轻易改变 这就是代理模式 代理 Proxy 模式的意图和适用性 意图 为其他对象提供一种代理以控制对这个对象的访问适用性 远程代理为一个对象在不同的地址空间提供局部代表虚代理在需要创建开销很大对象时缓存对象信息保护代理控制对原始对象的访问 代理 Proxy 模式的结构 代理 Proxy 模式的参与者 Proxy保存一个引用使得代理可以访问实体提供一个与Subject的接口相同的接口 这样代理就可以用来替代实体控制对实体的存取 并可能负责创建和删除它其他功能依赖于代理的类型Subject定义ConcreteSubject和Proxy的共用接口 在任何使用ConcreteSubject的地方都可以使用ProxyConcreteSubject定义Proxy所代表的实体 代理 Proxy 模式的应用示例 一个简单的数学计算程序 程序只负责简单的加减乘除运算 代理 Proxy 模式的效果分析 RemoteProxy为一个位于不同地址空间的对象提供一个局域代表对象将网络细节隐藏 客户端不必考虑网络的存在代理对象承担了大部份的网络通讯工作VirtualProxy创建一个资源消耗较大的对象 需要时才被真正创建代理对象可以在必要的时候才加载被代理对象代理可以对加载的过程加以优化 代理 Proxy 模式的效果分析 ProtectProxy控制对象的访问 可给不同用户提供不同级别的使用权限可以在运行时对用户权限进行检查CacheProxy为目标操作提供临时存储空间 以便多客户端共享FirewallProxy保护目标 防止恶意用户接近SynchronizationProxy使多用户能同时使用一个对象而没有冲突 组合 Composite 模式的由来 表达部分与整体的树形结构 机箱 计算机 显示器 键盘 鼠标 主板 CPU 硬盘 电源 显卡 网卡 组合 Composite 模式的由来 抽象单一对象 Leaf 键盘 鼠标 显示器 硬盘 电源 CPU 显卡 网卡组合对象 Composite 计算机 机箱 主板部件 Component 单一对象与组合对象的统称组合对象既可以包括单一对象 也可以包括组合对象 组合 Composite 模式的意图和适用性 意图 将对象组合成树形结构 表示 部分 整体 层次结构使用户对单一对象和组合对象使用具有一致性接口适用性表示对象的部分 整体层次结构忽略总体对象与单一对象差异 统一使用组合结构的所有对象 组合 Composite 模式的结构 组合 Composite 模式的参与者 组合 Composite 模式的参与者 Component为组合对象声明接口声明一个接口用于访问和管理Component的子组件Leaf表示叶节点对象 没有子节点定义图元对象的行为Composite定义复合部件的行为存储子部件Client通过Component接口操纵组合部件的对象 组合 Composite 模式的效果 定义了包含基本对象和组合对象的类层次结构简化客户代码 一致使用组合对象和单个对象容易增加新类型的组件用户使用Component类接口与组合结构中的对象进行交互 如果接收者是叶节点 直接处理请求 如果接收者是Composite 将请求发送给它的子部件 在转发请求之前和 或之后可能执行一些辅助操作 组合 Composite 模式的实现 显式的父对象的引用 在子对象中给出父对象的引用 可以很容易地遍历所有父对象最大化Component接口声明管理子部件的操作组件的存储 什么样的数据结构 结构型设计模式总结 Adapter Bridge FacadeAdapter用于两个已有的不兼容接口之间的转接Bridge用于将一个抽象与多个可能的实现进行桥接Facade用于为复杂的子系统定义一个新的简单易用的接口Composite Decorator和ProxyComposite用于构造对象 递归 组合结构Decorator用于为对象增加新的职责Proxy为目标对象提供一个替代者Flyweight针对细粒度对象的一种全局控制手段 行为型设计模式 模板模式 TemplatemethodPattern 观察者模式 OberserverPattern 迭代子模式 IteratorPattern 责任链模式 ChainofResponsibilityPattern 备忘录模式 MementoPattern 命令模式 CommandPattern 状态模式 StatePattern 访问者模式 VisitorPattern 中介者模式 MediatorPattern 策略模式 StrategyPattern 解释器模式 InterpreterPattern 行为型模式的主要内容 模板方法模式的由来 关注类对象职责分配 实现父类和子类对象之间职责的划分将多个类的共有内容提取到一个模板中的想法 是模板模式的重要思想使用继承机制使得父类和子类之间达到分工合作目的 父类完成流程 算法 框架 子类实现其具体工作 模板方法模式的意图和适用性 意图定义操作中算法的骨架 将一些步骤的执行延迟到其子类中 子类不需要改变算法结构即可重定义算法的某些步骤适用场合具有统一的操作步骤或操作过程 具有不同的操作细节 即存在多个具有同样操作步骤的应用场景 但某些具体的操作细节却各不相同 模板方法模式的结构 模板方法模式的参与者 AbstractTemplate定义一个 模板 或算法骨架 子类 使用该模板的客户 重定义模板中的操作 相当于根据模板填写内容 ConcreteTemplate实现模板定义的操作以完成算法中与特定子类相关的步骤 模板方法模式的效果分析 模板方法是一种代码复用技术 模板提取了 子类 的公共行为模板方法导致一种反向的控制结构 你别来找我 让我去找你 即 一个父类调用子类的操作 而不是相反可通过在抽象模板定义模板方法给出成熟算法步骤 同时又不限制步骤细节 具体模板实现算法细节不会改变整个算法骨架在抽象模板模式中 可以通过钩子方法对某些步骤进行挂钩 具体模板通过钩子可以选择算法骨架中的某些步骤 观察者模式的由来 将系统分割成一系列相互协作的类有也存在一些不足 需要维护相关对象间的一致性为维持一致性而使各类紧密耦合 可能降低其可重用性没有理由限定依赖于某数据对象的对象数目 对相同的数据对象可以有任意数目的不同用户界面 观察者模式的由来 观察者模式的意图和适用性 意图 定义对象间的一种一对多的依赖关系 当一个对象的状态发生改变时 所有依赖于它的对象都得到通知并被自动更新适用场合当一个抽象模型有两个方面 一方面依赖于另一方面 将二者封装在独立对象中以使它们可以独立被改变和复用一个对象的改变需要同时改变其它对象 但不知道具体有多少对象有待改变当一个对象必须通知其它对象 而它又不能假定其它对象是谁 换言之 不希望这些对象是紧密耦合的 观察者模式的结构 观察者模式的参与者 Subject 抽象的主题 即被观察的对象Observer 抽象的观察者ConcreteSubject 具体被观察对象ConcreteObserver 具体的观察者注意 在观察者模式中 Subject通过Attach和Detach方法添加或删除所关联的观察者 并通过Notify进行更新 让每个观察者观察到最新的状态 班主任老师有电话号码 学生需要知道班主任老师的电话号码以便于在合适时的时候拨打在这样的组合中 老师是一个被观察者 Subject 学生就是需要知道信息的观察者当老师的电话号码发生改变时 学生得到通知 并更新相应的电话记录 观察者模式的应用示例 观察者模式的应用示例 观察者模式分析 应用场景对一个对象状态的更新 需要其他对象同步更新 而且其他对象的数量动态可变对象仅需要将自己的更新通知给其他对象而不需要知道其他对象细节优点Subject和Observer之间是松偶合的 可以各自独立改变Subject在发送广播通知时 无须指定具体的Observer Observer可以自己决定是否要订阅Subject的通知高内聚 低偶合缺陷松偶合导致代码关系不明显 有时可能难以理解如果一个Subject被大量Observer订阅的话 在广播通知的时候可能会有效率问题 迭代子模式的由来 将对象职责分离 最大限度减少彼
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 大学生村官年度思想工作内容总结
- 大学生寒假社会实践调研报告
- 高竞争力面试题及答案精 编行业指导参考
- 在开学典礼暨教师节教师发言稿
- 小儿美克尔憩室超声课件
- 难点详解沪科版9年级下册期末测试卷含完整答案详解【必刷】
- 乡村住房转让协议书范本
- 抖店合作经营协议合同范本
- 营地驱蚊产品采购合同范本
- 兼职外教聘请协议书范本
- udi追溯管理制度
- 三一研发项目管理制度
- 轮胎公司中长期发展战略规划纲要(2025-2030年)
- 浙江省衢州市2023-2024学年高二下学期6月教学质量检测数学试题(含答案)
- 化妆品外包生产管理制度
- 颅内静脉窦血栓护理查房
- 成人重症患者颅内压增高防控护理专家共识
- 【聊城】2025年山东聊城科技职业学院(筹)公开招聘工作人员60人笔试历年典型考题及考点剖析附带答案详解
- 2024年国家中医药管理局直属事业单位招聘真题
- 读书分享《教师的语言力》
- 2025年5月上海普通高中学业水平等级性考试物理试题及答案
评论
0/150
提交评论