创建型设计模式-工厂模式

75 阅读3分钟
  • 简单工厂 (Simple Factory) :

把对象创建封装在接口中,通过不同标识,返回创建对象,客户不用自己new对象,不用了解对象创建详细过程。

缺点:不符合开闭原则

  • 工厂方法(Factory Method)

Factory基类提供纯虚函数(创建产品),定义派生类(具体工厂)负责创建对应的产品,可以做到不同产品在不同工厂创建,符合开闭原则,创建新工厂不影响原来的。

实际上,很多产品有关联,属于一个产品簇,应该放在同一个工厂去生产,而且可以控制工厂类的数量,方便维护。

  • 抽象工厂(Abstract Factory)

    具体的工厂负责产品簇里的所有产品

工厂模式:主要是封装了对象的创建

一、传统方式获取对象

 #include <iostream>
 ​
 class Car {
 public:
     Car(std::string name) : m_name(name) {}
     virtual void show() = 0;
 ​
 protected:
     std::string m_name;
 };
 ​
 class BMW : public Car {
 public:
     BMW(std::string name) : Car(name) {}
     void show() {
         std::cout << "获取一辆宝马" << std::endl;
     }
 };
 ​
 class Audi : public Car {
 public:
     Audi(std::string name) : Car(name) {}
     void show() {
         std::cout << "获取一辆奥迪" << std::endl;
     }
 };
 ​
 int main()
 {
     // 传统方式需要自己手动创建,其实直接跟工厂要就好了,用户不需要了解构造方法
     Car *p1 = new BMW("x1");
     Car* p2 = new Audi("A6");
 }

二、简单工厂

 #include <iostream>
 #include <memory>
 class Car {
 public:
     Car(std::string name) : m_name(name) {}
     virtual void show() = 0;
 ​
 protected:
     std::string m_name;
 };
 ​
 class Bmw : public Car {
 public:
     Bmw(std::string name) : Car(name) {}
     void show() {
         std::cout << "获取一辆宝马" << std::endl;
     }
 };
 ​
 class Audi : public Car {
 public:
     Audi(std::string name) : Car(name) {}
     void show() {
         std::cout << "获取一辆奥迪" << std::endl;
     }
 };
 ​
 enum CarType {
     BMW, AUDI
 };
 ​
 class SimpleFactory {
 public:
     Car* createCar(CarType ct) {
         switch (ct) {
         case BMW:
             return new Bmw("x1");
         case AUDI:
             return new Audi("A6");
         default:
             std::cerr << "参数错误" << std::endl;
             break;
         }
         return nullptr;
     }
 };
 ​
 int main()
 {
     std::unique_ptr<SimpleFactory> factory(new SimpleFactory());
     Car* p1 = factory->createCar(BMW);
     delete p1;
 }

缺点:

  • 不符合开闭原则,增加新对象就要修改createCar接口
  • 只有一个工厂,不符合实际

三、工厂方法

 #include <iostream>
 #include <memory>
 ​
 class Car {
 public:
     Car(std::string name) : m_name(name) {}
     virtual void show() = 0;
 ​
 protected:
     std::string m_name;
 };
 ​
 class Bmw : public Car {
 public:
     Bmw(std::string name) : Car(name) {}
     void show() {
         std::cout << "获取一辆宝马" << std::endl;
     }
 };
 ​
 class Audi : public Car {
 public:
     Audi(std::string name) : Car(name) {}
     void show() {
         std::cout << "获取一辆奥迪" << std::endl;
     }
 };
 ​
 class Factory {
 public:
     virtual Car* createCar(std::string name) = 0;
 };
 // 宝马工厂
 class BmwFactory : public Factory {
 public:
     Car* createCar(std::string name) {
         return new Bmw(name);
     }
 };
 // 奥迪工厂
 class AudiFactory : public Factory {
 public:
     Car* createCar(std::string name) {
         return new Audi(name);
     }
 };
 ​
 int main()
 {
     std::unique_ptr<Factory> bmwFty(new BmwFactory());
 ​
     Car* p1 = bmwFty->createCar("x6");
 }

总结:工厂有继承,车也有继承,哪家的工厂生产哪家的车。符合开闭原则

四、抽象工厂

上述代码一个产品一个工厂不合适,所以要抽象

 #include <iostream>
 #include <memory>
 ​
 // 系列产品1
 class Car {
 public:
     Car(std::string name) : m_name(name) {}
     virtual void show() = 0;
 ​
 protected:
     std::string m_name;
 };
 ​
 class Bmw : public Car {
 public:
     Bmw(std::string name) : Car(name) {}
     void show() {
         std::cout << "获取一辆宝马" << std::endl;
     }
 };
 ​
 class Audi : public Car {
 public:
     Audi(std::string name) : Car(name) {}
     void show() {
         std::cout << "获取一辆奥迪" << std::endl;
     }
 };
 ​
 // 系列产品二
 class Light {
 public:
     virtual void show() = 0;
 };
 class BmwLight : public Light {
     void show() { std::cout << "BMW Light" << std::endl; }
 };
 class AudiLight : public Light {
     void show() { std::cout << "Audi Light" << std::endl; }
 };
 ​
 ​
 // 工厂 ===>>> 抽象工厂(对有一组关联关系的产品簇提供产品对象的统一创建)
 class AbstractFactory {
 public:
     virtual Car* createCar(std::string name) = 0; // 工厂方法创建汽车
     virtual Light* createCarLight() = 0; // 工厂方法,创建汽车灯
 };
 // 宝马工厂
 class BmwFactory : public AbstractFactory {
 public:
     Car* createCar(std::string name) {
         return new Bmw(name);
     }
     Light* createCarLight() {
         return new BmwLight();
     }
 };
 // 奥迪工厂
 class AudiFactory : public AbstractFactory {
 public:
     Car* createCar(std::string name) {
         return new Audi(name);
     }
     Light* createCarLight() {
         return new AudiLight();
     }
 };
 ​
 int main()
 {
     std::unique_ptr<AbstractFactory> bmwFty(new BmwFactory());
     std::unique_ptr<Car> p1(bmwFty->createCar("x1"));
     std::unique_ptr<Light> l1(bmwFty->createCarLight());
     p1->show();
 }