设计模式笔记(C++实现/文字版)


  • 使用设计模式的目的:分离时间维度上的稳定和变化
  • 设计模式的最重要两大原则:开闭原则(开放拓展,关闭修改),依赖倒置
  • 常用的五大设计模式:策略模式,工厂模式,抽象工厂,单例模式,模板模式

策略模式

  • 目的:统一子类的接口,将每个子类独立封装,互相之间可以相互替代,根据需要灵活替代
  • 继承结构:定义一个基类作为父类,定义父类的虚函数作为接口。定义子类继承父类并重写
  • 使用时:定义一个基类的指针指向一个子类的实例化对象,调用基类指针的接口函数,因为该函数为虚函数,在运行时会体现出动态多态的特点,实际运行中会调用子类的重写函数
class BaseClass {
 public:
  virtual void calculate() = 0;
}

class SonClass: public BaseClass {
  public:
   void claculate() {
    // implementation
   }
}

BaseClass* base = new SonClass();
base->calculate(); 

工厂模式

  • 目的:解决对象创建过程中接口的紧耦合问题
  • 继承结构:定义一个基类工厂类作为父类,定义父类的虚函数create()作为接口。定义子类继承父类并重写create()函数
class ISplitter { };
class RealSplitter : public ISplitter {};

class BaseFactory {
 public:
  virtual ISplitter* create() = 0;
}

class RealFactory {
 public:
  virtual ISplitter* create() {
    return new RealSplitter();
  }
}

RealFactory real_factory = new RealFactory();
RealSplitter real_splitter = real_factory.create();

抽象工厂

  • 目的:解决一系列前后相关的对象创建过程中的依赖关系
  • 场景:假设存在Redis,MySql,Redis三种不同的数据库,实际开发中从数据库中读取数据需要三个操作:获取权限,连接,读取。对于不同数据库的三个操作无法混用,因此工厂模式将三个操作统一封装进一个抽象工厂

单例模式

  • 目的:项目中的某一个类只需要唯一的一个实例,即仅创建一次(即避免多个对象创建过程中过的开销问题或唯一性问题)
    • 饿汉式:先创建实例,再调用(使用static关键词)
    • 懒汉式:
    // 非线程安全版本
    Singleton *Singleton::getInstance() {
      if (instance == nullptr) {
        instance = new Singleton();
      }
      return instance;
    }
    
    // 线程安全版本,但锁的代价过高
    Singleton *Singleton::getInstance() {
      Lock lock;    // 锁的调用为伪代码
      if (instance == nullptr) {
        instance = new Singleton();
      }
      return instance;
    }
    
    // 双检查锁,但是内存读取reorder不安全
    Singleton *Singleton::getInstance() {
      if (instance == nullptr) {
        Lock lock;    // 锁的调用为伪代码
        if (instance == nullptr) {
          // 该行正常执行顺序:分配内存 -> 在分配的内存上构造对象 -> 将内存首地址赋给指针
          // reorder后可能的执行顺序:分配内存 -> 将内存首地址赋给指针 -> 在分配的内存上构造对象。若在第二步执行完成后,第三步未完成前,该线程被阻塞,则其他线程能拿到该内存地址,存在使用未初始化对象的问题。解决方案:加锁/原子操作
          instance = new Singleton();
        }
      }
      return instance;
    }
    

模板模式

  • 场景:项目中的某个功能是固定执行多个具有不同先后顺序的步骤,其中的部分步骤已由库函数提供,部分步骤需要用户自定义。模板模式就是将该规定好的步骤封装到库函数中,减少用户需要了解的上下文内容,专注于需要开发的内容
// 库函数部分
class Library {
 public:
  void Run() {
    step1();
    step2();
    step3();
    step4();
    step5();
  }

 protected:
  void step1() {
      cout << "i am step 1" << endl;
  }
  void step2() {
      cout << "i am step 2" << endl;
  }
  void step3() {
      cout << "i am step 3" << endl;
  }
  virtual void step4() = 0;
  virtual void step5() = 0;
};

// 用户部分
class Application: public Library {
 protected:
  bool step4() {
    cout << "i am step 4" << endl;
  }
  void step5() {
    cout << "i am step 5" << endl;
  }
};

int main() {
  Library* lib = new Application();
  lib->Run();

  return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值