Overview of Patterns

  • 针对特定上下文中出现的常见软件问题提出解决方案

  • 捕获软件参与者之间的重复结构和动态,以促进成功设计的重用

  • 帮助解决关键的软件设计力量

    Flexibility 灵活性 Extensibility 可扩展性 Dependability 可靠性 Predictability 可预测性 Scalability 可延展性 Efficiency 效率

  • 一般编纂设计策略、约束和“最佳实践”的专业知识

  • 可以在类中编码并按原样重用的数据结构(即链表、哈希表)

  • 复杂的特定领域设计(针对整个应用程序或子系统)

  • 如果它们不是熟悉的数据结构或复杂的特定领域子系统,它们是什么?

    • 为解决特定上下文中的一般设计问题而定制的通信对象和类的描述

The “gang of four” (GoF)

设计模式书目录 23 种不同的模式

  • 不同类别问题的解决方案,在 C++ 和 Smalltalk 中
  • 问题及解决方案适用范围广,多人使用多年
  • 模式建议在分析、设计和编程中重用的机会
  • GOF 以结构化格式呈现每个模式

Elements of Design Patterns

设计模式有4个基本要素:

  • 图案名称:增加设计师的词汇量 -- Pattern
  • 问题:意图、上下文、何时应用 -- Problem
  • 解决方案:类UML结构,抽象代码 -- Solution
  • 结果:结果和权衡 -- Consequences

Three Types of GoF Patterns

  • 创作模式: Creational Patterns
    • 处理初始化和配置对象
  • 结构模式: Structural Patterns
    • 类或对象的组合
    • 解耦接口和类的实现
  • 行为模式: Behavioral Patterns
    • 处理对象社会之间的动态交互
    • 他们如何分配责任

Structural patterns

  • 组装对象以实现新功能
  • 示例:代理 Proxy
    • 代理充当另一个对象的方便代理或占位符。
    • 例子?
      • Remote Proxy 远程代理:不同地址空间中对象的本地代表
      • Virtual Proxy 虚拟代理:代表应该按需加载的大对象
      • Protected Proxy 受保护代理 :保护对原始对象的访问
Proxy Pattern - Structure
  • 意图
    • 为另一个对象提供代理或占位符以控制对其的访问。
  • 结构

Type: Structural Patterns
  • 适配器:将类的接口转换为客户期望的接口
  • 桥:将抽象与许多可能的实现联系起来
  • 合成的:将部分-整体层次结构表示为树结构
  • 装饰器:动态地为对象附加额外的责任
  • 正面:简化子系统的接口
  • 蝇量级:高效共享多个细粒度对象
  • 代理:为另一个对象提供代理或占位符以控制对其的访问

Adapter pattern

  • 问题:如何解决不兼容的接口(incompatible interfaces)或为具有不同接口的相似组件提供稳定的接口?
  • 解决方案:通过一个中间适配器将原来的接口组件转换成另一个。

Using an Adapter: adapt postSale request to SOAP XML interface

Adapter pattern uses inheritance

Object Adapter

优点
  • 减少与实现特定细节的耦合--Reduces coupling
  • 多态性和间接性揭示了提供的基本行为 -- Polymorphism and indirection
  • 在类图中包含新类中的设计模式名称(例如,TaxMasterAdapter),代码根据已知的设计模式与其他开发人员进行交流

Composite Pattern

Composite 允许客户端统一处理单个对象和对象的组合。

Facade Pattern 外观图案

  • 为子系统中的一组对象提供统一的接口。
  • Facades 允许我们提供一个封闭的架构

Structure of the Facade Pattern

Type: Creational Patterns

  • 单例:保证访问单个(唯一)实例 -- Singleton
  • 简单工厂:创建专门的、复杂的对象 -- Simple Factory
  • 抽象工厂:打造专业化工厂家族 -- Abstract Factory
  • 工厂方法:定义一个用于创建对象的接口,但让子类决定实例化哪个类 -- Factory Method
  • Builder:一步一步构造一个复杂的对象
  • 原型:从原型克隆新实例 -- Prototype
  • 延迟初始化:延迟昂贵的创建,直到需要它 -- Lazy initialization

Singleton pattern

  • 一个只有实例并提供全局访问点的类
  • 全局变量可能很危险! (副作用,打破信息隐藏)

Simple Factory pattern

  • 背景/问题 Context/Problem
    • 当有特殊考虑时,谁应该负责创建对象,例如复杂的逻辑,希望分离创建责任以获得更好的内聚性等等
  • 解决方案 Solution
    • 创建一个 Pure Fabrication 来处理创建
How does Simple Factory work

Factory can create different objects

Factory Pattern

  • 意图:
    • 定义用于创建对象的接口,但让子类决定实例化哪个类。

Abstract Factory Pattern

example

The Client remains blissfully unaware of the various concrete classes in this example.

Advantages 优点

  • 将复杂创建的职责分离为内聚的辅助类
  • 隐藏复杂的创建逻辑,例如从文件初始化
  • 处理内存管理策略,例如回收或缓存

Behavioral Patterns

  • 责任链:Chain of Responsible
    • 请求委托给负责的服务提供商
  • 命令: Command
    • Request 或 Action 是一流的对象,因此是可存储的
  • 迭代器: Iterator
    • 按顺序聚合和访问元素
  • 翻译: Interpreter
    • 小语法的语言解释器
  • 调解员: Mediator
    • 协调其同事之间的互动
  • 纪念: Memento
    • Snapshot 私下捕获和恢复对象状态
  • 观察员: Observer
    • 当观察到的对象发生变化时,观察者会自动更新
  • 状态: State
    • 其行为取决于其状态的对象
  • 战略: Strategy
    • 用于选择多种算法之一的抽象
  • 模板方法: Template Method
    • 派生类提供的带有一些步骤的算法
  • 游客: Visitor
    • 应用于异构对象结构元素的操作

Observer pattern

  • 意图:
    • 定义对象之间的一对多依赖关系,这样当一个对象改变状态时,它的所有依赖对象都会得到通知并自动更新
  • 在模型-视图-控制器框架中使用(MVC)
    • 模型是问题域
    • 视图是窗口系统
    • 控制器是鼠标/键盘控制

Command pattern

  • 概要或意图:Synopsis or Intent
    • 将一个请求封装成一个对象,从而让你参数化具有不同请求、队列或日志请求的客户端,并支持可撤销的操作
  • 解决方案: Solution
    • Command 对象的接口可以是一个简单的 execute() 方法
    • 额外的方法可以支持撤销和重做
    • 命令可以是持久的并且可以全局访问,就像普通对象一样
Command Pattern Structure:

  • 参与者(参与此模式的类和/或对象)Participants:
    • Command 声明用于执行操作的接口
    • ConcreteCommand 定义了 Receiver 对象和通过调用 Receiver 上的相应操作来实现 Execute 之间的绑定
    • 调用者(Invoker)要求命令执行请求
    • 接收者(Receiver)知道如何执行与执行请求相关的操作
    • 客户端(Client)创建一个 ConcreteCommand 对象并设置其接收器
  • 结果 Consequences:
    • 您可以撤消/重做任何命令(undo/redo)
      • 每个命令存储恢复状态所需的内容
    • 您可以将命令存储在堆栈或队列中(store Commands)
      • 命令处理器模式维护历史
    • 添加新命令很容易,因为您不必更改现有类(you do not have to change existing classes )
      • 命令是一个抽象类,你可以从中派生出新的类
      • execute()、undo() 和 redo() 是多态函数

State Pattern – Motivation

  • 考虑一个代表网络连接的 TCPConnection 类。
  • 当 TCPConnection 对象收到来自其他对象的请求时,它会根据其当前状态做出不同的响应。

  • 意图:允许对象在其内部状态改变时改变其行为。 从客户端的角度来看,该对象似乎改变了它的类。

Builder Pattern

Builder - Example

  • 意图:将复杂对象的构建与其表示分开,以便相同的构建过程可以创建不同的表示。
  • 结构

  • 客户端创建 Director 对象并使用所需的 Builder 对象对其进行配置。
  • 每当应该构建产品的一部分时,Director 都会通知构建者。
  • Builder 处理来自主管的请求并向产品添加部件。
  • 客户端从构建器中检索产品。

Prototype Pattern

  • 意图:使用原型实例指定要创建的对象种类,并通过复制此原型来创建新对象。
  • 结构 客户要求原型克隆自身

Bridge Pattern

  • 意图:将抽象与其实现分离,以便两者可以独立变化。

Decorator Pattern

  • 绘画示例

    • 虽然画挂在墙上可以有框也可以没有框,但往往是加框的,而真正挂在墙上的是框。
  • 意图

    • 动态地为对象附加额外的职责。
    • 装饰器提供了一种灵活的替代子类来扩展功能。

Strategy Pattern

  • 意图

    • 定义一系列算法,封装每个算法,并使它们可以互换。 策略让算法独立于使用它的客户端而变化。
  • 结构

  • 策略定义了一组可以互换使用的算法。

  • 到机场的交通方式是战略的一个例子。

Iterator Pattern

  • 诸如列表之类的聚合对象应该为您提供一种访问其元素而不暴露其内部结构的方法。
  • 关键思想是把访问和遍历的责任从列表对象中取出,放入迭代器对象中。

  • 意图
    • 提供一种顺序访问聚合对象的元素而不暴露其底层表示的方法。
  • 结构

Benefits of Design Patterns

  • 设计模式可实现软件架构的大规模重用,并有助于文档系统

  • 模式明确地捕捉专家知识和设计权衡,并使其更广泛地可用

  • 模式有助于改善开发人员的沟通

  • 模式名称形成一个共同的词汇