设计模式一(创建型模式)

前言

模式就是解决问题的固定套路

设计模式(Design pattern)就是一套经过前人反复使用,总结出来的程序设计经验

设计模式总共分为三大类:

  • 创建型模式 ,该模式通常和对象的创建有关,涉及到对象实例化的方式。包括:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式五种;
  • 结构型模式,结构型模式描述的是如何组合类和对象来获得更大的结构。包括:代理模式、装饰者模式、适配器模式、桥接模式、组合模式、外观模式、享元模式共7种模式。
  • 行为型模式,用来描述对类或对象怎样交互和怎样分配职责。共有:模板模式、命令模式、责任链模式、策略模式、中介者模式、观察者模式、备忘录模式、访问者模式、状态模式、解释器模式、迭代器模式11种模式。

本文使用具体实例快速了解各设计模式的基本思想

七大原则

开发封闭原则

开闭原则是指软件实体是可以扩展的,但是不可修改

模块和函数是对扩展(提供方)开放的,对修改(使用方)关闭的,对于一个新的需求,对软件的改动应该是通过增加代码来实现的,而不是通过改动代码实现的

开闭原则是面向对象的核心,是最基础、最重要的设计原则

对于C++类来说,对类的改动是通过增加代码实现的,而不是修改代码实现的,通过虚基类的继承和虚函数的实现来完成一个类功能的扩充

单一职责原则

对类来说,类的职责应该是单一的,一个类只能对外提供一种功能

单一职责相当于降低了各种职责的耦合度,如果一个类负责多个职责,那么改动类的某一职责时,可能会影响到类行使其他职责的能力

依赖倒置原则

抽象不应该依赖于细节,细节应该依赖于抽象。换句话说,依赖于抽象接口,而不是依赖于具体的类的实现,也就是面向抽象接口编程

依赖倒置原则是面向对象编程的标志

在具体软件设计时,上层模块不应该依赖于底层模块,底层模块更不应该依赖上层模块,而是上层模块和底层模块都向中间靠拢,共同依赖于二者中间的抽象接口层

整个软件程序设计的依赖关系应该终止于抽象接口层,上层和底层互不关心,甚至使用什么编程语言都不关心。抽象接口层提供一个标准或者协议,它对上提供访问的接口,对下提供实现的标准,抽象接口层本身不执行任何操作,具体的功能由它的实现去完成

接口隔离原则

一个接口对外只提供一种功能,不同功能应该通过不同的接口提供

里氏替换原则

任何地方出现的抽象类,都可以使用该抽象类的实现类来代替

合成复用原则

优先使用对象组合而不是继承原则

迪米特法则

一个类对于其它类知道的越少越好

迪米特法则降低了耦合度

各个模块之间通过一个接口来实现调用,而模块之间不需要知道对方的内部实现逻辑,并且一个模块的内部改变也不会影响到另一个模块(黑盒原理)。如果两个类不直接通信,那么这两个类就不应当发生直接的相互作用。如果一个类需要调用另一个类的某个方法的话,可以通过第三个类转发这个调用。

创建型模式

单例模式

单例模式顾名思义就是指一个类只能创建一个实例对象,并且对外提供一个全局访问点来访问这个唯一的实例对象

单例模式主要分为两类:

  • 饿汉式单例模式:一开始就创建好了一个唯一的对象;
  • 懒汉式单例模式:在使用实例对象的时候去创建该唯一的对象;

懒汉式

class Singleton {
 private:
  // 私有化构造函数
  Singleton() = default;

  // 删除拷贝构造函数和赋值运算符
  Singleton(const Singleton&) = delete;
  Singleton& operator=(const Singleton&) = delete;

 public:
  static Singleton* GetSingle() {  // 提供对位访问点
    if (single == NULL) {          // 保证单例,只new一次
      mutex.lock();
      if (single == NULL) {  // 二次检查
        single = new Singleton;
      }
      mutex.unlock();
    }
    return single;  // 静态成员属于整个类,没有this指针
  }

 private:
  // static 成员,类定义的所有对象共有static成员
  static Singleton* single;  // 指针,不能是变量,否则编译器不知道如何分配内存
};

Singleton* Singleton::single = NULL;  // 告诉编译器分配内存

注:懒汉式不能保证线程安全,使用互斥锁进行二次检查

饿汉式


class Singleton {
 private:
  Singleton() = default;
  Singleton(const Singleton&) = delete;
  Singleton& operator=(const Singleton&) = delete;

 public:
  static Singleton* GetSingle() { return single; }

 private:
  static Singleton* single;
};

Singleton* Singleton::single = new Singleton;  // 一开始就 new 了一个对象

工厂模式

简单工厂模式

定义了一个创建对象的类,由这个类来封装实例化对象的行为

// 抽象产品类
class ProductInterface {
 public:
  virtual void Print() = 0;
};

// 具体产品类
class ProductA : public ProductInterface {
 public:
  virtual void Print() { std::cout << "Product A" << std::endl; }
};
class ProductB : public ProductInterface {
 public:
  virtual void Print() { std::cout << "Product B" << std::endl; }
};

// 工厂类
class Factory {
 public:
  ProductInterface* Produce(int flag) {
    ProductInterface* temp = NULL;
    switch (flag) {  // 不符合开闭原则
      case 1:
        temp = new ProductA;
        break;
      case 2:
        temp = new ProductB;
        break;
      default:
        temp = NULL;
        break;
    }
    return temp;
  }
};

工厂模式

定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类

// 抽象产品类
class ProductInterface {
 public:
  virtual void Print() = 0;
};

// 具体产品类
class ProductA : public ProductInterface {
 public:
  virtual void Print() { std::cout << "Product A" << std::endl; }
};
class ProductB : public ProductInterface {
 public:
  virtual void Print() { std::cout << "Product B" << std::endl; }
};

// 抽象工厂类
class FactoryInterface {
 public:
  virtual ProductInterface* Produce() = 0;
};

// 具体工厂类
class ProductAFactory : public FactoryInterface {
 public:
  virtual ProductInterface* Produce() { return new ProductA; }
};
class ProductBFactory : public FactoryInterface {
 public:
  virtual ProductInterface* Produce() { return new ProductB; }
};

抽象工厂模式

定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类

// 抽象产品类
class ProductInterface {
 public:
  virtual void Print() = 0;
};

// 具体产品类
class ProductA1 : public ProductInterface {
 public:
  virtual void Print() { std::cout << "Product A1" << std::endl; }
};
class ProductA2 : public ProductInterface {
 public:
  virtual void Print() { std::cout << "Product A2" << std::endl; }
};
class ProductB1 : public ProductInterface {
 public:
  virtual void Print() { std::cout << "Product B1" << std::endl; }
};
class ProductB2 : public ProductInterface {
 public:
  virtual void Print() { std::cout << "Product B2" << std::endl; }
};

// 抽象工厂类
class FactoryInterface {
 public:
  virtual ProductInterface* ProduceA() = 0;
  virtual ProductInterface* ProduceB() = 0;
};

// 具体工厂类
class ProductOneFactory : public FactoryInterface {
 public:
  virtual ProductInterface* ProduceA() { return new ProductA1; }
  virtual ProductInterface* ProduceB() { return new ProductB1; }
};
class ProductTwoFactory : public FactoryInterface {
 public:
  virtual ProductInterface* ProduceA() { return new ProductA2; }
  virtual ProductInterface* ProduceB() { return new ProductB2; }
};

建造者模式

封装一个复杂对象构造过程,并允许按步骤构造,使得同样的构建过程可以创建不同的表示

// 最终产品类
class Product {
 public:
  void set_part_a(std::string a) { this->part_a = a; }
  void set_part_b(std::string b) { this->part_b = b; }
  void set_part_c(std::string c) { this->part_c = c; }
  // 获取属性
  std::string get_part_a() { return this->part_a; }
  std::string get_part_b() { return this->part_b; }
  std::string get_part_c() { return this->part_c; }

  void Show() {
    std::cout << get_part_a() << " " << get_part_b() << " " << get_part_c()
              << std::endl;
  }

 private:
  std::string part_a;
  std::string part_b;
  std::string part_c;
};

// 抽象建造者类
class Builder {
 public:
  virtual void BuildPartA() = 0;
  virtual void BuildPartB() = 0;
  virtual void BuildPartC() = 0;

  virtual Product* get_product() = 0;
};

// 具体建造者类
class BuilderOne : public Builder {
 private:
  Product* production;

 public:
  BuilderOne() { this->production = new Product; }
  virtual void BuildPartA() { this->production->set_part_a("A1"); }
  virtual void BuildPartB() { this->production->set_part_b("B1"); }
  virtual void BuildPartC() { this->production->set_part_c("C1"); }
  virtual Product* get_product() { return this->production; }
};

// 指挥者类
class Director {
 public:
  explicit Director(Builder* builder) { this->builder = builder; }
  // 建造逻辑
  void BuilderLogic() {
    this->builder->BuildPartA();
    this->builder->BuildPartB();
    this->builder->BuildPartC();
  }

 private:
  Builder* builder;
};

原型模式

通过复制现有实例来创建新的实例,无需知道相应类的信息

// 原型接口类
class PrototypeInterface {
 public:
  virtual ~PrototypeInterface() {}
  virtual PrototypeInterface* Clone() = 0;
  virtual void Display() = 0;
};

// 具体原型类
class PrototypeA : public PrototypeInterface {
 private:
  std::string data;

 public:
  explicit PrototypeA(const std::string& data) : data(data) {}

  PrototypeInterface* Clone() override {
    PrototypeA* temp = new PrototypeA("new");
    *temp = *this;
    return temp;
  }

  void Display() override { std::cout << "Prototype A: " << data << std::endl; }
};