简介
简单工厂: 工厂是非抽象的,具体
工厂模式: 工厂是抽象的, 且只生成一种产品
抽象工厂: 工厂是抽象的, 且可以生产很多产品,所以他面对于一个问题,如果想要增加一类产品的话, 抽象工厂模式就得修改抽象, 就是对修改不关闭
简单工厂模式
一般简单工厂模式的缺点是:当需要增加新的产品时, 需要修改工厂代码,这是对修改不关闭的
好的设计模式应该是对扩展开放, 对修改关闭
下面使用一种注册的模式,来规避该缺点。
#include <iostream>
#include <utility>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
using namespace std;
class Pizza {
public:
void bake() {
cout << name << "::bake" << endl;
}
void cut() {
cout << name << "::cut" << endl;
}
virtual ~Pizza() = 0;
string name;
};
Pizza::~Pizza() {}
class TranditonalPizza : public Pizza {
public:
TranditonalPizza() {
name = "TranditonalPizza";
}
};
class NewPizza : public Pizza {
public:
NewPizza() {
name = "NewPizza";
}
};
#define StoreAddNewPizza(obj, name) \
obj.AddNew<name>(#name)
class PizzaFactory {
private:
unordered_map<string, function<unique_ptr<Pizza>()>> canMakeGood;
public:
void init() {
canMakeGood["TranditonalPizza"] = []() {
return unique_ptr<Pizza>(new TranditonalPizza());
};
}
PizzaFactory() {}
template<typename Type>
void NewPizzaLearned(const string &name) {
canMakeGood[name] = []() {
return unique_ptr<Pizza>(new Type());
};
}
unique_ptr<Pizza> createPizza(const string &name) {
if (canMakeGood.count(name) == 0) {
return nullptr;
}
return canMakeGood[name]();
}
};
class PizzaStore {
private:
unique_ptr<PizzaFactory> pf;
public:
PizzaStore() : pf(make_unique<PizzaFactory>()) {
pf->init();
}
template<typename T>
void AddNew(const string &name) {
pf->template NewPizzaLearned<T>(name);
}
unique_ptr<Pizza> orderPizza(const string &name) {
auto pz = pf->createPizza(name);
if (!pz) {
return pz;
}
pz->bake();
pz->cut();
return pz;
}
};
int main() {
// 简单工厂模式
PizzaStore ps;
auto pz = ps.orderPizza("TranditonalPizza");
if (!pz) {
cout << "sorry, pizza store cannot make this pizza\n";
}
pz = ps.orderPizza("NewPizza");
if (!pz) {
cout << "sorry, pizza store cannot make this pizza\n";
}
// 注册新的 pizza
StoreAddNewPizza(ps, NewPizza);
pz = ps.orderPizza("NewPizza");
if (!pz) {
cout << "sorry, pizza store cannot make this pizza\n";
}
}