设计模式

设计模式 #

零、反射 #

含义 #

在程序运行时,动态获取对象信息以及调用对象方法的能力。

要解决的问题 #

在程序运行时,通过类的名称字符串来生成类的对象。

一、简单工厂模式 #

含义 #

把实例化的操作单独放到一个类中,即:工厂负责生产对象。

要解决的问题 #

让使用者不需要知道内部细节,就能创建对象,实现解耦。

组成 #

  1. 抽象的Product,描述接口。
  2. 具体Product, 创建的目标类。
  3. 工厂类,被外界调用,根据传入不同参数从而创建不同类的实例。

实际代码 #

工厂类有个静态方法,可以用switch case控制返回哪个类的实例。外界只要调用并传入参数即可。

改进:通过反射机制,去掉switch case,添加新Product不用修改。

1

应用场景 #

  • 当外界/客户端只关心传入参数,不关心内部逻辑时,解耦

缺点 #

  • 处于中心位置,需要知道所有创建细节,职责过于繁重;
  • 要加新的产品时,要修改工厂类。

二、工厂方法模式 #

含义 #

定义一个用于创建对象的接口,由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。

要解决的问题 #

  1. 让使用者不需要知道内部细节,就能创建对象,实现解耦。
  2. 新加产品时,只要添加具体产品和具体工厂就可以。

组成 #

  1. 抽象的Product:描述接口。
  2. 具体Product:具体产品。
  3. 抽象工厂类
  4. 具体工厂类

实际代码 #

客户端怎么调用?

  1. new 具体工厂,得到具体工厂实例;
  2. 用具体工厂,得到具体Product类。

应用场景 #

  • 写日志到文件/数据库

三、抽象工厂 #

含义 #

创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。

要解决的问题 #

  1. 让使用者不需要知道内部细节,就能创建对象,实现解耦。
  2. 新加产品时,只要添加具体产品和具体工厂就可以。

组成 #

  1. 抽象的Product:描述接口。
  2. 具体Product:具体产品。
  3. 抽象工厂类
  4. 具体工厂类

实际代码 #

Client 通过 AbstractFactory 同时调用两个方法来创建出两个对象

客户端怎么调用?

  1. new 具体工厂,得到具体工厂实例;
  2. 用具体工厂,得到具体Product类。

应用场景 #

四、策略模式 #

  1. 目的:如果对象的某个行为,在不同的场景中有不同的实现方式,即有多种策略或算法,不要用很多个的if-else去做判断和选择,而是封装每个策略,并使它们可以切换,从而达到解耦的效果,满足开闭原则。
  2. 具体:三种角色
    1. 策略接口:负责定义接口
    2. 具体的策略:负责实现
    3. Context上下文:保存具体策略的实例。可以动态地改变具体的策略。
  3. 实例:多种支付方法(支付宝、微信支付)、多种分享方法(微信、QQ)。

五、单例模式 #

含义 #

确保一个类只有一个实例,并提供该实例的全局访问点。

实现方式 #

  1. 单例类:
    1. 构造函数私有化
    2. 有个私有的静态指针变量
    3. 有个共有的静态方法获取实例
  • 饿汉式:还没被用到,就先初始化
  • 懒汉式
class Singleton {
    private:
    Singleton() {};
    ~Singleton() {};
    Singleton(const Singleton&) {}; // 拷贝构造函数
    Singleton& operator=(const Singleton&); // 赋值构造函数
    public:
    static Singleton& getInstance() {
    static Singleton instance; //  保证内部静态变量的线程安全性
    return instance;
    }
}