C++实现抽象工厂模式Abstract Factory Pattern

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

通过抽象工厂做提供的接口,可以创建产品的家族,利用这个接口书写代码,我们的代码将从实际工厂解耦,以便在不同上下文中实现各式各样的工厂,制造除各种不同的产品。例如:不同的区域、不同的操作系统、不同的外观及操作。

因为代码从实际的产品中解耦了,所以我们可以替换不同的工厂来取得不同的行为。


抽象工厂:创建产品家族,让制造的相关产品集合起来。

工厂方法:把客户代码从需要实例化的具体类中解耦。当目前还不知道将来需要实例化哪些具体类时,可以用工厂方法。


#include 
#include 
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 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 createVeggies() {
		std::vector 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;
	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.

你可能感兴趣的:(Head,First,Design,Patterns设计模式,抽象工厂模式,c++,设计模式)