工厂模式

最初的解决方案:

class PizzaStore
{
public:
	Pizza *orderPizza(string type){
		Pizza *pizza;
/* comment_1:由于要不断有新的类型的pizza产生,这段代码要经常修改 */
		if (type == aaa) {
			pizza = new aaa;
		} else if (type == bbb) {
			pizza = new bbb;
		}
		else {
			// ...
		}
/* comment_1 */
		pizza->bake();
		pizza->cut();
		pizza->box();
		return pizza;
	}
};


下面用工厂模式来处理:

1. 简单工厂

把经常需要变动的那部分封装

/* 封装用的类,封装变化的部分 */
class SimplePizzaFactory
{
	Pizza *createPizza(string type) {
		Pizza pizza;
		/* 上面comment_1注释的都搬到这里来 */
		return pizza;
	}
};

/* 新的解决方案 */
class PizzaStore
{
public:
	PizzaStore() {
		simplePizzaFactory = new SimplePizzaFactory;
	}
	Pizza *orderPizza(string type) {
		Pizza *pizza = simplePizzaFactory->createPizza(type);
		pizza->bake();
		pizza->cut();
		pizza->box();
		return pizza;
	}
private:
	SimplePizzaFactory *simplePizzaFactory;
};

2. 工厂方法

简单的工厂造成的一个问题是生产出来的pizza没有多样性,都是一模一样,下面看工厂方法的解决方案。

/* 工厂方法的解决方案 */
class PizzaStore
{
public:
	Pizza *orderPizza(string type) {
		Pizza *pizza = createPizza(type);
		pizza->bake();
		pizza->cut();
		pizza->box();
		return pizza;
	}
protected:
	/* createPizza方法期待继承者自己实现,随便什么类型 */
	virtual Pizza *createPizza(string type) = 0;
};
工厂方法可以做到的是:假如有ABCD四种pizza,不同的PizzaStore继承者所生产的Pizza都会在这四种里选择。

有的时候虽然都是A,可是有的要刷辣酱,而有的要刷甜酱,怎么办?也就是说A的“酱”这个属性值是不一样的!有没有必要建立一个“酱”的抽象对象呢,然后它派生出了“辣酱”和“甜酱”?有必要!整个结构就变成下面这样了(引出抽象工厂):

3. 抽象工厂

父类:原料P、原料Q、原料R、原料S

子类:P1, P2, P3, Q1, Q2, Q3, Q4, R1, R2, R3, S1, S2

父类:Pizza

子类:Pizza A(P, Q)、Pizza B(P, Q, R)、Pizza C(P, S)、Pizza D(Q, R, S)

注意:每种Pizza有的属性并不一定完全相同,有的Pizza要加酱,而有的不要加。现在我们又需要一个工厂,来生产PQRS原料。

/* 生产原料的抽象工厂 */
class IngredientFactory
{
public:
	P *createP() = 0;
	Q *createQ() = 0;
	R *createR() = 0;
	S *createS() = 0;
};

由上面这个抽象类我们就可以派生出各种各样的原料工厂了,足以满足Pizza A(P, Q)、Pizza B(P, Q, R)、Pizza C(P, S)、Pizza D(Q, R, S)的需求了。

注意:虽然Pizza A只需要PQ两种原料,针对A的原料工厂也不能只实现createP和createQ,否则这个工厂仍旧是个抽象工厂(c++的特性)。

PizzaStore的接口要这样写了:

/* 新的PizzaStore,无非就是多了一个原料工厂的属性,用以决定本工厂具体使用哪种PQRS */
class PizzaStore
{
public:
	PizzaStore(IngredientFactory f) {
		ingredientFactory = f;
	}
	Pizza *orderPizza(string type) {
		Pizza *pizza = createPizza(type);
		pizza->bake();
		pizza->cut();
		pizza->box();
		return pizza;
	}
protected:
	virtual Pizza *createPizza(string type) = 0;
	IngredientFactory ingredientFactory;
};

PizzaStore的继承者应该这样实现createPizza了:

/* PizzaStore的子类,具体的PizzaStore */
Pizza *createPizza(string type) {
	Pizza *pizza;
	if (type == A) {
		pizza = new PizzaA(ingredientFactory);
	}
	else if (type == B) {
		pizza = new PizzaB(ingredientFactory);
	}
	else {
		// ...
	}
};

Pizza类应该这样写了:

/* 新的Pizza类 */
class Pizza
{
public:
	Pizza() {
		p=0; q=0; r=0; s=0;
	}
private:
	P p; Q q; R r; S s;
};
/* Pizza的继承者 */
class PizzaA : public Pizza
{
public:
	PizzaA(IngredientFactory f) {
		p = f.createP();
		q = f.createQ();
		/* 看上面,A类Pizza只有PQ两种原料 */
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值