抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
通过抽象工厂做提供的接口,可以创建产品的家族,利用这个接口书写代码,我们的代码将从实际工厂解耦,以便在不同上下文中实现各式各样的工厂,制造除各种不同的产品。例如:不同的区域、不同的操作系统、不同的外观及操作。
因为代码从实际的产品中解耦了,所以我们可以替换不同的工厂来取得不同的行为。
抽象工厂:创建产品家族,让制造的相关产品集合起来。
工厂方法:把客户代码从需要实例化的具体类中解耦。当目前还不知道将来需要实例化哪些具体类时,可以用工厂方法。
#include <iostream>
#include <vector>
using namespace std;
创建产品家族
创建原料
class Dough {};
class ThinCrustDough:public Dough {};
class Sauce {};
class MarinaraSauce :public Sauce {};
class Cheese {};
class ReggianoCheese:public Cheese {};
class Veggies {};
class Garlic:public Veggies {};
class Onion:public Veggies {};
class Mushroom :public Veggies {};
class RedPepper :public Veggies {};
class Pepperoni {};
class SlicedPepperoni:public Pepperoni {};
class Clams {};
class FreshClams:public Clams {};
创建抽象工厂
class PizzaIngredientFactory {
public:
virtual Dough* createDough() = 0;
virtual Sauce* createSauce() = 0;
virtual Cheese* createCheese() = 0;
virtual std::vector<Veggies*> createVeggies() = 0;
virtual Pepperoni* createPepperoni() = 0;
virtual Clams* createClams() = 0;
};
创建产品家族
class NYPizzaIngredientFactory :public PizzaIngredientFactory {
public:
Dough* createDough() {
return new ThinCrustDough();
}
Sauce* createSauce() {
return new MarinaraSauce();
}
Cheese* createCheese() {
return new ReggianoCheese();
}
Clams* createclams() {
return new FreshClams();
}
std::vector<Veggies*> createVeggies() {
std::vector<Veggies*> vegs;
vegs.push_back(new Garlic());
vegs.push_back(new Onion());
vegs.push_back(new Mushroom());
vegs.push_back(new RedPepper());
return vegs;
}
Pepperoni* createPepperoni() {
return new SlicedPepperoni();
}
Clams* createClams() {
return new FreshClams();
}
};
class Pizza {
public:
std::string name;
Dough *dough;
Sauce *sauce;
Cheese *cheese;
Clams* clams;
std::vector<Veggies*> veggies;
Pepperoni *pepperoni;
virtual void prepare() = 0;
void bake() {
printf("Bake for 25 minutes at 350\n");
}
void cut() {
printf("Cutting the pizza into diagonal slices\n");
}
void box() {
printf("Place pizza in offical PizzaStore box\n");
}
std::string getName() {
return name;
}
void setName(std::string in_name) {
name = in_name;
}
};
class CheesePizza :public Pizza {
private:
PizzaIngredientFactory* ingredientFactory;
public:
CheesePizza(PizzaIngredientFactory* ingredientFact) {
ingredientFactory = ingredientFact;
}
void prepare() {
printf("Preparing %s\n", name.c_str());
dough = ingredientFactory->createDough();
sauce = ingredientFactory->createSauce();
cheese = ingredientFactory->createCheese();
}
};
class ClamPizza :public Pizza {
private:
PizzaIngredientFactory* ingredientFactory;
public:
ClamPizza(PizzaIngredientFactory* ingredientFact) {
ingredientFactory = ingredientFact;
}
void prepare() {
printf("Preparing %s\n", name.c_str());
dough = ingredientFactory->createDough();
sauce = ingredientFactory->createSauce();
cheese = ingredientFactory->createCheese();
clams = ingredientFactory->createClams();
}
};
class PepperoniPizza :public Pizza {
private:
PizzaIngredientFactory* ingredientFactory;
public:
PepperoniPizza(PizzaIngredientFactory* ingredientFact) {
ingredientFactory = ingredientFact;
}
void prepare() {
printf("Preparing %s\n", name.c_str());
dough = ingredientFactory->createDough();
sauce = ingredientFactory->createSauce();
cheese = ingredientFactory->createCheese();
pepperoni = ingredientFactory->createPepperoni();
}
};
class VeggiePizza :public Pizza {
private:
PizzaIngredientFactory* ingredientFactory;
public:
VeggiePizza(PizzaIngredientFactory* ingredientFact) {
ingredientFactory = ingredientFact;
}
void prepare() {
printf("Preparing %s\n", name.c_str());
dough = ingredientFactory->createDough();
sauce = ingredientFactory->createSauce();
cheese = ingredientFactory->createCheese();
veggies = ingredientFactory->createVeggies();
}
};
class PizzaStore {
public:
Pizza* orderPizza(std::string type) {
//Pizza* pizza = factory->createPizza(type);
Pizza* pizza = createPizza(type);
pizza->prepare();
pizza->bake();
pizza->cut();
pizza->box();
return pizza;
}
virtual Pizza* createPizza(std::string type) = 0;
};
class NYPizzaStore :public PizzaStore {
public:
Pizza* createPizza(std::string type) {
Pizza* pizza = NULL;
PizzaIngredientFactory* ingredientFactory = new NYPizzaIngredientFactory();
if (type._Equal("cheese")) {
pizza = new CheesePizza(ingredientFactory);
pizza->setName("New York Style Cheese Pizza\n");
}
else if (type._Equal("veggie")) {
pizza = new VeggiePizza(ingredientFactory);
pizza->setName("New York Style Veggie Pizza\n");
}
else if (type._Equal("clam")) {
pizza = new ClamPizza(ingredientFactory);
pizza->setName("New York Style Clam Pizza\n");
}
else if (type._Equal("pepperoni")) {
pizza = new PepperoniPizza(ingredientFactory);
pizza->setName("New York Style Pepperoni Pizza\n");
}
else {
return NULL;
}
return pizza;
}
};
测试
void main() {
PizzaStore *nyStore = new NYPizzaStore();
Pizza* pizza = nyStore->orderPizza("cheese");
printf("Ethan ordered a %s\n\n", pizza->getName().c_str());
}
参考:
1. EricFreeman, FreemanElisabeth, 弗里曼, et al. Head First设计模式[M]. 中国电力出版社, 2007.