C++实现工厂方法模式Factory Method Pattern

设计原则6:要依赖抽象,不要依赖具体类。(又称依赖倒置原则Dependency Inversion Principle)

不能让高层组件依赖低层组件,而且,不管高层组件或低层组件,两者都应该依赖于抽象。


如何避免在OO设计中违反依赖倒置原则:

  • 变量不可以持有具体类的引用。

                如果使用new,就会持有具体类的引用。可以改用工厂来避开这样的作法

  • 不要让类派生自具体类。

                如果派生自具体类,就会依赖具体类。请派生自一个抽象。

  • 不要覆盖基类中已实现的方法。

                如果覆盖基类已实现的方法,那么基类就不是一个真正适合被继承的抽象。基类中已实现的方法,应该由所有的子类共享。


工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

工厂方法模式将产品的“实现”从“使用”中解耦。如果增加产品或者改变产品的实现,Creator并不会收到影响。


#include <iostream>
#include <vector>
using namespace std;

定义产品类

class Pizza {
public:
	std::string name;
	std::string dough;
	std::string sauce;
	std::vector<std::string> toppings;
	void prepare() {
		printf("Preparing %s\n",name.c_str());
		printf("Tossing dough...\n");
		printf("Adding sauce...\n");
		printf("Adding toppings:\n");
		for (int i = 0; i < toppings.size(); i++) {
			printf("    %s\n", toppings[i].c_str());
		}
	}
	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;
	}
};

class CheesePizza :public Pizza {
public:
	CheesePizza() {
		name = "Cheese Pizza";
		dough = "Regular Crust";
		sauce = "Marinara Pizza Sauce";
		toppings.push_back("Fresh Mozzarella");
		toppings.push_back("Parmesan");
	}
};

class NYStyleCheesePizza :public Pizza {
public:
	NYStyleCheesePizza() {
		name = "NY Style Sauce and Cheese Pizza";
		dough = "Thin Crust Dough";
		sauce = "Marinara Sauce";
		toppings.push_back("Grated Reggiano Cheese");
	}
};

class ChicagoStyleCheesePizza :public Pizza {
public:
	ChicagoStyleCheesePizza() {
		name = "Chicago Style Deep Dish Cheese Pizza";
		dough = "Extra Thick Crust Dough";
		sauce = "Plum Tomato Sauce";
		toppings.push_back("Shredded Mozzarella Cheese");
	}

	void cut() {
		printf("Cutting the pizza into square slices\n");
	}

};

class PepperoniPizza :public Pizza {
public:
	PepperoniPizza() {
		name = "Pepperoni Pizza";
		dough = "Crust";
		sauce = "Marinara sauce";
		toppings.push_back("Sliced Pepperoni");
		toppings.push_back("Sliced Onion");
		toppings.push_back("Grated parmesan cheese");
	}
};

class NYStylePepperoniPizza :public Pizza {
public:
	NYStylePepperoniPizza() {
		name = "NY Style Sauce and Pepperoni Pizza";
		dough = "Crust";
		sauce = "Marinara sauce";
		toppings.push_back("Sliced Pepperoni");
		toppings.push_back("Sliced Onion");
		toppings.push_back("Grated parmesan cheese");
	}
};

class ChicagoStylePepperoniPizza :public Pizza {
public:
	ChicagoStylePepperoniPizza() {
		name = "Chicago Style Deep Dish Pepperoni Pizza";
		dough = "Crust";
		sauce = "Marinara sauce";
		toppings.push_back("Sliced Pepperoni");
		toppings.push_back("Sliced Onion");
		toppings.push_back("Grated parmesan cheese");
	}
};

class ClamPizza :public Pizza {
public:
	ClamPizza() {
		name = "Clam Pizza";
		dough = "Thin crust";
		sauce = "White garlic sauce";
		toppings.push_back("Clams");
		toppings.push_back("Grated parmesan cheese");
	}
};

class NYStyleClamPizza :public Pizza {
public:
	NYStyleClamPizza() {
		name = "NY Style Clam Pizza";
		dough = "Thin crust";
		sauce = "White garlic sauce";
		toppings.push_back("Clams");
		toppings.push_back("Grated parmesan cheese");
	}
};

class ChicagoStyleClamPizza :public Pizza {
public:
	ChicagoStyleClamPizza() {
		name = "Chicago Style Clam Pizza";
		dough = "Thin crust";
		sauce = "White garlic sauce";
		toppings.push_back("Clams");
		toppings.push_back("Grated parmesan cheese");
	}
};

class VeggiePizza :public Pizza {
public:
	VeggiePizza() {
		name = "Veggie Pizza";
		dough = "Crust";
		sauce = "Marinara sauce";
		toppings.push_back("Shredded mozzarella");
		toppings.push_back("Grated parmesan");
		toppings.push_back("Diced onion");
		toppings.push_back("Sliced mushrooms");
		toppings.push_back("Sliced red pepper");
		toppings.push_back("Sliced black olives");
	}
};

class NYStyleVeggiePizza :public Pizza {
public:
	NYStyleVeggiePizza() {
		name = "NY Style Veggie Pizza";
		dough = "Crust";
		sauce = "Marinara sauce";
		toppings.push_back("Shredded mozzarella");
		toppings.push_back("Grated parmesan");
		toppings.push_back("Diced onion");
		toppings.push_back("Sliced mushrooms");
		toppings.push_back("Sliced red pepper");
		toppings.push_back("Sliced black olives");
	}
};

class ChicagoStyleVeggiePizza :public Pizza {
public:
	ChicagoStyleVeggiePizza() {
		name = "Chicago Style Veggie Pizza";
		dough = "Crust";
		sauce = "Marinara sauce";
		toppings.push_back("Shredded mozzarella");
		toppings.push_back("Grated parmesan");
		toppings.push_back("Diced onion");
		toppings.push_back("Sliced mushrooms");
		toppings.push_back("Sliced red pepper");
		toppings.push_back("Sliced black olives");
	}
};

定义创建者类

抽象创建者:抽象创建者通常会包含依赖于抽象产品的代码,而这些抽象产品由子类制造,创建者不需要真的知道在制造哪种具体产品。

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) {
		if (type._Equal("cheese")) {
			return new NYStyleCheesePizza();
		}
		else if (type._Equal("pepperoni")) {
			return new NYStylePepperoniPizza();
		}
		else if (type._Equal("clam")) {
			return new NYStyleClamPizza();
		}
		else if (type._Equal("veggie")) {
			return new NYStyleVeggiePizza();
		}
		else {
			return NULL;
		}
	}
};

class ChicagoPizzaStore :public PizzaStore {
public:
	Pizza* createPizza(std::string type) {
		if (type._Equal("cheese")) {
			return new ChicagoStyleCheesePizza();
		}
		else if (type._Equal("pepperoni")) {
			return new ChicagoStylePepperoniPizza();
		}
		else if (type._Equal("clam")) {
			return new ChicagoStyleClamPizza();
		}
		else if (type._Equal("veggie")) {
			return new ChicagoStyleVeggiePizza();
		}
		else {
			return NULL;
		}
	}
};

测试程序

void main() {
	PizzaStore *nyStore = new NYPizzaStore();
	PizzaStore *chicagoStore = new ChicagoPizzaStore();

	Pizza* pizza = nyStore->orderPizza("cheese");
	printf("Ethan ordered a %s\n\n", pizza->getName().c_str());

	pizza = chicagoStore->orderPizza("cheese");
	printf("Joel ordered a %s\n\n", pizza->getName().c_str());

}

参考:

1. EricFreeman, FreemanElisabeth, 弗里曼, et al. Head First设计模式[M]. 中国电力出版社, 2007.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值