商业鬼才教你 工厂方法 && 抽象工厂 模式

时间:2022-07-25
本文章向大家介绍商业鬼才教你 工厂方法 && 抽象工厂 模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

故事线

广军把奶茶店开起来之后,接下来便是要购置机器和材料了。

对于饮料机,摆在他眼前的有两个选择,其一是“水龙头式饮料机”,长这样:

另一种是“冲泡式”奶茶机,是这种:

他想了想,选了第二种。 他说:第一种机器,如果要再上新品,只能再加个桶,麻烦,这机器还不知道能不能再加桶,而奶茶机就比较友好了,要泡什么奶茶,只要把材料配一下,搅拌一下,加热/冷藏 一下,就可以拿去卖了,想出什么新品就出什么新品。

到这里就完了吗?不不不,我们的广军可不是个傻子,仅仅卖奶茶,可不能满足他,他决定再购置一台汉堡机,一台香肠机、一手奶茶,一手汉堡加香肠,汉堡吃的口渴了再点杯奶茶,奶茶单喝没意思,顺手点个汉堡,汉堡吃不太饱再来几条香肠。

这时候,他又发现,这些机器如果零散摆放,当客流量大的时候要跑动跑西累成狗,那怎么可以?绝对不允许,于是他又买了个工作台。

简直是商业鬼才!!

工厂方法模式

这个故事的前半部分,就是工厂方法模式的一个实现场景。

什么是工厂方法模式呢? 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟到其子类。 如果广军他买了前面那个可乐机,那么这个饮料单就被限制死了,不灵活。但是他买了第二种奶茶机,那么他只要把材料倒进机器中,其他交给机器。如果要出什么新品,那就换一些原料罢了。

我们来看一张 工厂方法模式的类图:

代码实现

#include<iostream>

using namespace std;

//奶茶主类
class Milk {
public:
	virtual void set_taste() = 0;//设置口味
	virtual void add_burdening() = 0;//加料
};

//双皮奶
class custard :public Milk {
public:
	void set_taste() { cout << "草莓味双皮奶" << endl; }
	void add_burdening() { cout << "加珍珠" << endl; }
};

//珍珠奶茶
class pearl :public Milk {
public:
	void set_taste() { cout << "香草味珍珠奶茶" << endl; }
	void add_burdening() { cout << "加椰果" << endl; }
};

//拿铁
class coffee :public Milk {
public:
	void set_taste() { cout << "拿铁" << endl; }
	void add_burdening() { cout << "不加料" << endl; }
};

//巧克力瑞纳冰
class ruinaice :public Milk {
public:
	void set_taste() { cout << "巧克力瑞纳冰" << endl; }
	void add_burdening() { cout << "加奶油" << endl; }
};

//所有饮品定义完毕,接下来定义一台机器
//template<class T>
class abstractMachin {
public:
	virtual void createMilk(Milk *c) = 0;
};

//机器具体实现
//template<class T>
class Machin :public abstractMachin {
public:
	void createMilk(Milk *c) {
		c->set_taste();
		c->add_burdening();
	}
};

//现在材料有了,机器也有了,是时候做奶茶了
class Boss {
	 //老板就是那个main()
};

int main() {
	//初始化一个机器
	abstractMachin* am = new Machin();
	//先做瑞纳冰
	Milk* ruina = new ruinaice();
	am->createMilk(ruina);

	return 0;
}

抽象工厂模式

什么是抽象工厂模式,它的定义也是很抽象的了:为创建一组相关或互相依赖的对象提供一个接口,而且无需指定它们的具体类。

喏,通用类图:

话不多说,太抽象了,还是看我们故事中的图吧(工作台 == 抽象机器):

可以考虑对抽象类使用模板,来看看代码实现:

#include<iostream>

using namespace std;

//奶茶主类
class Milk {
public:
	virtual void set_taste() = 0;//设置口味
	virtual void add_burdening() = 0;//加料
};

//双皮奶
class custard :public Milk {
public:
	void set_taste() { cout << "草莓味双皮奶" << endl; }
	void add_burdening() { cout << "加珍珠" << endl; }
};

//珍珠奶茶
class pearl :public Milk {
public:
	void set_taste() { cout << "香草味珍珠奶茶" << endl; }
	void add_burdening() { cout << "加椰果" << endl; }
};

//拿铁
class coffee :public Milk {
public:
	void set_taste() { cout << "拿铁" << endl; }
	void add_burdening() { cout << "不加料" << endl; }
};

//巧克力瑞纳冰
class ruinaice :public Milk {
public:
	void set_taste() { cout << "巧克力瑞纳冰" << endl; }
	void add_burdening() { cout << "加奶油" << endl; }
};


//汉堡主类
class humberger {
public:
	virtual void add_burdening() = 0;//加料
};

//牛肉堡
class beef :public humberger {
public:
	void add_burdening() { cout << "不加辣" << endl; }
};

//鸡腿堡
class chicken :public humberger {
public:
	void add_burdening() { cout << "微辣" << endl; }
};

//香辣堡
class piquancy :public humberger {
public:
	void add_burdening() { cout << "巨辣" << endl; }
};

//接下来定义一个工作台
template<class T1, class T2>
class abstractMachin {
public:
	virtual void createMilk(T1* c) = 0;
	virtual void createHumb(T2* c) = 0;
};

//工作台具体实现
template<class T1,class T2>
class Machin :public abstractMachin<T1,T2> {
public:
	void createMilk(T1* c) {
		c->set_taste();
		c->add_burdening();
	}
	void createHumb(T2* c) {
		c->add_burdening();
	}
};


int main()
{
	//初始化一个工作台
	abstractMachin<Milk,humberger>* am = new Machin<Milk,humberger>();
	//先做瑞纳冰
	Milk* ruina = new ruinaice();
	am->createMilk(ruina);

	//再来个牛肉堡
	abstractMachin<Milk,humberger>* bm = new Machin<Milk,humberger>();
	beef* bf = new beef();
	bm->createHumb(bf);

	return 0;
}

还行吧。

创作不易,顺手收藏好习惯,划着划着,就找不到了。