《二十三種設計模式》 第五篇 “工廠模式” (C++實現)

工廠模式是二十三中設計模式中最常用的一種模式之一,幾乎所有開源的框架都有用到工廠模式。

工廠模式可以分爲三種:簡單工廠模式工廠方法模式抽象工廠模式

其中,簡單工廠模式並沒有列入到二十三中設計模式中,應爲其太簡單了,而且違反了開閉原則

工廠方法模式 與 抽象工廠模式都是簡單工廠模式的延伸。

對於工廠模式,其最主要的作用就是定義對象返回!
就是另外再定義類來定義需要使用到的對象,而不再是在main函數中定義對象。
通俗的講就是分配對象返回(工廠模式就是用來生產對象的)。


簡單工廠模式

簡單工廠模式是三個工廠模式中最簡單的,其生產可以集中到一個了類中進行分配對象,進行有效的管理。

舉一個例子:
現在市面上有許多品牌的手機,假設小米、華爲、蘋果三個品牌的手機都是在同一個工廠裏生產的,且都是同一時間進行生產,那麼工廠就可以決定生產哪個品牌的手機了(想生產哪個品牌的手機就生產哪個品牌的手機),這樣就是使用到了簡單工廠模式的原理。

可以使用在任何需要new對象的項目中!

UNL類圖:
在這裏插入圖片描述

小米、華爲、蘋果三個類都是繼承自手機類,然後手機生產工廠類的實現又依賴於他們三個品牌手機類。

如果還是不懂的話,看下面代碼你就會明白他是怎麼使用的了。

下面看代碼吧:

#include <iostream>
#include <Windows.h>

using namespace std;

// 三臺手機的類型
enum PHONE_TYPE {
	MIUI,
	HUAWEI,
	IPHONE
};

// 手機類
class MobilePhone {
public:
	virtual void description() = 0;		// 純虛函數
};

// 小米手機類
class Miui : public MobilePhone {
public:
	void description() {				// 描述信息
		cout << "小米手機" << endl;
	}
};

// 華爲手機類
class Huawei : public MobilePhone {
public:
	void description() {
		cout << "華爲手機" << endl;
	}
};

// 蘋果手機類
class Iphone : public MobilePhone {
public:
	void description() {
		cout << "蘋果手機" << endl;
	}
};


// 手機生產工廠
class Factory {
public:

	// 根據傳入來的類型,進行對應的分配對象返回
	MobilePhone *manufacturePhone(PHONE_TYPE type) {
		switch (type) {
			case MIUI:
				return (new Miui());	// 生產小米手機(生成小米手機對象返回)
				break;
			case HUAWEI:
				return (new Huawei());	// 生產華爲手機(生成華爲手機對象返回)
				break;
			case IPHONE:
				return (new Iphone());	// 生產蘋果手機(生成蘋果手機對象返回)
				break;
			default:
				return NULL;			// 返回NULL
				break;
		}
	}
};



int main(void) {
	// 建立工廠對象
	Factory *factory = new Factory;

	// 工廠對象調用manufacturePhone方法給父類指針對象分配對象
	MobilePhone *xiaoMi = factory->manufacturePhone(MIUI);
	// 打印描述信息
	xiaoMi->description();

	MobilePhone * huaWei = factory->manufacturePhone(HUAWEI);
	huaWei->description();

	MobilePhone *iphone = factory->manufacturePhone(IPHONE);
	iphone->description();


	// 釋放內存
	delete factory;
	delete xiaoMi;
	delete huaWei;
	delete iphone;

	system("pause");
	return 0;
}

運行結果:
在這裏插入圖片描述

簡單工廠模式雖然簡單明瞭,但是如果需要增加類的話,就得去修改生產手機工廠中類了,這就違反了開閉原則,所以衍生了工廠方法模式。


工廠方法模式

在這裏插入圖片描述

工廠方法模式,不再只是由一個手機生產的工廠生產手機了,而是每種品牌都有自己的生產工廠,也就是說簡單工廠模式中的工廠類不再使用他了,而是使用它的子類進行各自的生產手機。

既你想生產什麼手機就生產什麼手機,完全不會涉及到其他手機廠商,如果有刪除或者增加手機品牌,完全不需要去修改其他手機廠商的代碼,這就很好的體現了開閉原則。

可以使用在任何需要new對象的項目中!

如下面的UML圖:
在這裏插入圖片描述
此時手機生產工廠不再運作,而是交由他的子類們運作生產。

看代碼就懂了:

#include <iostream>
#include <Windows.h>

using namespace std;

//enum PHONE_TYPE {
//	MIUI,
//	HUAWEI,
//	IPHONE
//};

// 手機類
class MobilePhone {
public:
	virtual void description() = 0;		// 純虛函數
};

// 小米手機類
class Miui : public MobilePhone {
public:
	void description() {				// 描述信息
		cout << "小米手機" << endl;
	}
};

// 華爲手機類
class Huawei : public MobilePhone {
public:
	void description() {
		cout << "華爲手機" << endl;
	}
};

// 蘋果手機類
class Iphone : public MobilePhone {
public:
	void description() {
		cout << "蘋果手機" << endl;
	}
};



// 手機生產工廠
class Factory {
public:
	virtual MobilePhone *manufacturePhone() = 0;	// 純虛函數
};


// 小米手機生產工廠
class MiuiFactory : public Factory {
public:

	// 生產小米手機(生成小米手機對象返回)
	MobilePhone *manufacturePhone() {
		return (new Miui());
	}
};


// 華爲手機生產工廠
class HuaweiFactory : public Factory {
public:

	// 生產華爲手機(生成華爲手機對象返回)
	MobilePhone* manufacturePhone() {
		return (new Huawei());
	}
};


// 蘋果手機生產工廠
class IphoneFactory : public Factory {
public:

	// 生產蘋果手機(生成蘋果手機對象返回)
	MobilePhone* manufacturePhone() {
		return (new Iphone());
	}
};



int main(void) {
	// 定義工廠指針對象
	Factory *factory = new MiuiFactory;
	// 工廠對象調用manufacturePhone方法給父類指針對象分配對象
	MobilePhone *xiaoMi = factory->manufacturePhone();
	// 打印描述信息
	xiaoMi->description();


	// 從新給工廠對象分配對象
	factory = new HuaweiFactory;
	MobilePhone *huaWei = factory->manufacturePhone();
	huaWei->description();


	// 從新給工廠對象分配對象
	factory = new IphoneFactory;
	MobilePhone *iphone = factory->manufacturePhone();
	iphone->description();


	// 釋放內存
	delete factory;
	delete xiaoMi;
	delete huaWei;
	delete iphone;

	system("pause");
	return 0;
}

運行結果:
在這裏插入圖片描述


抽象工廠模式

抽象工廠模式是工廠方法模式的升級版。

也就是說,抽象工廠模式他不再僅限於生產手機,他還可以生產電腦、音箱、電視機等等。它不再是侷限於生產一種類型的生產工廠。

下面我們以上面的手機工廠爲基礎,在拓展出一個升級版的手機生產工廠,手機二代,畢竟手機也是需要更新換代的嘛。

請看UML類圖:
在這裏插入圖片描述
跟工廠方法模式的類圖差不多,就是多了一個升級版的手機類。

看代碼就懂了:

#include <iostream>
#include <Windows.h>

using namespace std;


// 手機類
class MobilePhone {
public:
	virtual void description() = 0;		// 純虛函數
};

// 小米手機類
class Miui : public MobilePhone {
public:
	void description() {				// 描述信息
		cout << "小米手機" << endl;
	}
};

// 華爲手機類
class Huawei : public MobilePhone {
public:
	void description() {
		cout << "華爲手機" << endl;
	}
};

// 蘋果手機類
class Iphone : public MobilePhone {
public:
	void description() {
		cout << "蘋果手機" << endl;
	}
};


// 升級版手機類
class NewMobilePhone {
public:
	virtual void newDescription() = 0;
};


// 升級版小米手機類
class NewMiui : public NewMobilePhone {
public:
	void newDescription() {
		cout << "小米手機二代" << endl;
	}
};


// 升級版華爲手機類
class NewHuawei : public NewMobilePhone {
public:
	void newDescription() {
		cout << "華爲手機二代" << endl;
	}
};


// 升級版蘋果手機類
class NewIphone : public NewMobilePhone {
public:
	void newDescription() {
		cout << "蘋果手機二代" << endl;
	}
};


// 手機生產工廠
class Factory {
public:

	virtual MobilePhone *manufacturePhone() = 0;	// 純虛函數

	virtual NewMobilePhone *newManufacturePhone() = 0;	// 純虛函數
};


// 小米手機生產工廠
class MiuiFactory : public Factory {
public:

	// 生產小米手機(生成小米手機對象返回)
	MobilePhone *manufacturePhone() {
		return (new Miui());
	}

	// 生產升級版小米手機(生成小米手機二代對象返回)
	NewMobilePhone *newManufacturePhone() {
		return (new NewMiui());
	}
};


// 華爲手機生產工廠
class HuaweiFactory : public Factory {
public:

	// 生產華爲手機(生成華爲手機對象返回)
	MobilePhone *manufacturePhone() {
		return (new Huawei());
	}


	// 生產升級版華爲手機(生成華爲手機二代對象返回)
	NewMobilePhone *newManufacturePhone() {
		return (new NewHuawei());
	}
};


// 蘋果手機生產工廠
class IphoneFactory : public Factory {
public:

	// 生產蘋果手機(生成蘋果手機對象返回)
	MobilePhone *manufacturePhone() {
		return (new Iphone());
	}


	// 生產升級版蘋果手機(生成蘋果手機二代對象返回)
	NewMobilePhone *newManufacturePhone() {
		return (new NewIphone());
	}
};



int main(void) {
	// 定義工廠指針對象
	Factory *factory = new MiuiFactory;
	// 生產小米手機
	MobilePhone *xiaoMi = factory->manufacturePhone();
	// 生產小米手機二代
	NewMobilePhone *newXiaoMi = factory->newManufacturePhone();
	xiaoMi->description();
	newXiaoMi->newDescription();


	// 給工廠對象分配華爲手機對象
	factory = new HuaweiFactory;
	MobilePhone *huaWei = factory->manufacturePhone();
	NewMobilePhone *newHuaWei = factory->newManufacturePhone();
	huaWei->description();
	newHuaWei->newDescription();


	// 給工廠對象分配蘋果手機對象
	factory = new IphoneFactory;
	MobilePhone* iphone = factory->manufacturePhone();
	NewMobilePhone* newIphone = factory->newManufacturePhone();
	iphone->description();
	newIphone->newDescription();


	// 釋放內存
	delete factory;
	delete xiaoMi;
	delete newXiaoMi;
	delete huaWei;
	delete newHuaWei;
	delete iphone;
	delete newIphone;

	system("pause");
	return 0;
}

運行結果:
在這裏插入圖片描述


總結:
到了這裏,貌似工廠模式中的三種用法也講完,不知道觀看此片博文的朋友有沒有看懂呢?按一個方向去想,工廠模式就是生成對象返回的;這樣想會不會明白一點呢。
一定要記住,開發中工廠模式是很常用的一種設計模式,必須要學會!

重在理解吧,先把代碼搞懂了,在去看類圖,兩者想着結合,相信一定會看懂的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章