- 简单工厂 (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();
}