23种经典设计模式,其中5种创建型模式,7种结构型模式,11种行为模式。

记忆方法:ABFPS - ABCDFFP - CCIIMMOSSTV

  • 创建型模式(ABFPS)
    封装了实例化一个类的过程。由此可以得到很大的灵活性:什么被创建,谁创建它,怎样被创建,何时创建,都可以被自由配置。

    A - Abstract Factory 抽象工厂
    给定一组接口,这些接口用来创建对象而用的。实际的创建工作由具体的工厂类完成,因此,可以通过不同的工厂来创建不同的对象。

    结构图
    设计模式笔记 - 创建型模式_第1张图片 

    优点:
       1. 分离了被创建的类与它的使用者,使用者只能通过被创建的类提供的接口来使用它。
       2. 易于交换被创建的类系列。并且易于维护同一系列的一致性。很简单,因为一个系列的类创建于一个具体工厂中。
    缺点:
       1. 不容易增加新的被创建的类。这要求要增加抽象工厂的接口,以及所有具体工厂的接口。

    一些结论性的东西
       1. 一般具体的工厂用单件(Singleton)来实现,因为一个系列的类只需要一个工厂。
       2. 抽象工厂类里面的方法其实都是工厂方法(Factory Method)。
       3. 可以通过给2中的工厂方法增加参数来增加创建的种类,但是不安全。因为只能返回一个公共接口,有时会需要向下强转。

    B - Builder 生成器
    创建一个复合对象时使用,封装不同部分的创建过程。

    结构图
    设计模式笔记 - 创建型模式_第2张图片 

    协作图
    设计模式笔记 - 创建型模式_第3张图片 

    优点:
       1. 改变Builder可以改变复合对象的表示。
       2. 改变Director可以改变复合对象内部组合顺序以及方式,从而得到更精细的控制。

    一些结论性的东西
       1. ConcreteBuilder一般有一个方法来取得最终得到的对象。当Director引导Builder构造结束之后,所创造的复杂对象有时候需要从ConcreteBuilder中取得。因为通常使用Builder的情况下,所得到的对象大多差异比较大,以至于没必要定义一个公共的父类;同时一般Builder的使用者很容易得到具体的Builder类,不需要提供抽象的接口。
       2. Builder和Abstract Factory的一个重大区别:前者是最后才返回所创建的对象,而后者是每一步都立刻返回一个对象。
       3. Builder可以用于计算复杂对象内部组件的个数等特殊应用(Counting Builder)。

    F - Factory Method 工厂方法
    一个类A通过定义一个创建对象B的接口,将B类实例化延迟到A的子类。

    结构图
    设计模式笔记 - 创建型模式_第4张图片

    优点:
       1. 可以利用工厂方法实现一个默认创建,由子类去扩展。

    一些结论性的东西
       1. 可以参数化工厂方法,结合子类的重写,变化非常丰富。
       2. 在c++中,工厂方法实际上就是一个返回新对象的虚函数,所以绝对不能在构造函数中调用。
       3. 抽象工厂类中的所有方法一般都是工厂方法。

    P - Prototype 原型
    通过复制原型对象来得到新对象。

    结构图
    设计模式笔记 - 创建型模式_第5张图片 

    优点:
       1. 复制一个对象不必知道该对象的确切类型
       2. 具有Abstract Factory以及Builder的所有优点
       3. 减少子类的构造
       4. 可以用此模式实现类的动态装载
    缺点:
       1. Clone()操作有时候并不容易实现,并且有深浅拷贝的区别

    一些结论性的东西
       1. 需要一个原型管理器(Prototype Manager)来管理原型。
       2. 有时候,克隆的对象需要手动初始化。
       3.  Concrete Factory也可以通过Prototype来实现。

    S - Singleton 单件
    保证一个类只有一个实例,提供一个全局访问点。

    结构图
    设计模式笔记 - 创建型模式_第6张图片 

    优点:
       1. 对唯一实例的受控访问。实例是唯一的,访问控制是随心所欲得;甚至可以控制实例的数目使其不再唯一。
       2. 避免全局变量。

    一些结论性的东西
       1. Singleton类一般将构造函数不声明为public,以防止类被外部创建
       2. c++中,可以保存一个静态类指针(static Singleton* _instance),该指针可以被赋值为其子类对象(见3)
       3. 对于c++中单件的获取函数( static Singleton* Instance()),其中可以对(_instance)针对各种不同情况进行赋值(比如赋值给子类对象)