永遠記住,你的存在是有意義的,
你很重要,
你是被愛著的,
而且你為這個世界帶來了無可取代的東西。
-- 麥克西 《男孩、鼴鼠、狐貍和馬》--
從零開始了解設計模式
- 抽象工廠模式
抽象工廠模式
今天我們一起來探究抽象工廠模式,這是對工廠模式的進階實現。通常我們將工廠模式與抽象工廠模式比作一維數組與二維數組。
工廠模式我們可以創建出一種類別的實例,而如果我們此時這種類別存在若干個變種,這時就可以通過抽象工廠模式進行創建。
比如現在正在制作一塊魔幻rpg類型游戲,每個角色都有武器與防具兩種裝備。武器存在大劍,法杖,拳套等,防具有護盾,魔法書,披風等。對于這個背景,就有兩個維度。為了實現這個功能可以如下設計:
#include<iostream>using namespace std;
//裝備基類
class Weapon {
public:virtual void use() = 0;
};
//防具基類
class Armour {
public:virtual void equip() = 0;
};//大劍
class Sword : public Weapon{
public:void use() {cout << "use sword" << endl;}
};
//法杖
class Staff : public Weapon {
public:void use() {cout << "use staff" << endl;}
};//護盾
class Shield : public Armour {
public:void equip() override {cout << "equip shield" << endl;}
};
//斗篷
class Cloak : public Armour {
public:void equip() {cout << "equip cloak" << endl;}
};//角色裝備工廠
class EquipmentFactory {
public:virtual Weapon* createWeapon() = 0;virtual Armour* createArmour() = 0;
};class WarriorFactory : public EquipmentFactory {
public:Weapon* createWeapon() override{return new Sword();}Armour* createArmour() override {return new Shield();}};class MageFactory : public EquipmentFactory {
public:Weapon* createWeapon() override {return new Staff();}Armour* createArmour() override {return new Cloak();}
};class Character {
public:Character(EquipmentFactory* factory) :_factory(factory),weapon(nullptr),armour(nullptr) {}//角色展現出來的裝備特性void equip() {weapon = _factory->createWeapon();armour = _factory->createArmour();//調用裝備使用方法weapon->use();armour->equip();}private:EquipmentFactory* _factory;Weapon* weapon = nullptr;Armour* armour = nullptr;
};int main() {//創建戰士EquipmentFactory* warriorFactory = new WarriorFactory();Character warrior(warriorFactory);warrior.equip();EquipmentFactory* mageFactory = new MageFactory();Character mage(mageFactory);mage.equip();return 0;}
根據這個例子,我們可以總結一下抽象工廠的要素:
- 抽象產品:如weapon與Armour基類,約定了具體產品的接口聲明,限制他們必須具有的功能
- 具體產品:如sword,staff ,shield類,這是實際發揮作用的產品,是最終被抽象工廠實例化的對象
- 抽象工廠:負責聲明一組接口,來創建抽象產品。
- 具體工廠:具體工廠負責實例化具體產品。
抽象工廠模式通常在以下場景中使用:
- 跨平臺GUI框架:qt, GTK+,wxWidgets對平臺的不同組件進行封裝
- 游戲引擎文件系統:不同操作系統上的文件操作api是不同的,當針對不同平臺進行導出發布時,游戲引擎底層幫助我們完成了對不同平臺文件讀寫的屏蔽與兼容。文件系統內部的writer與Reader讀寫器,就可以通過抽象工廠創建
- 游戲界面風格主題:針對不同主題實現不同UI組件的靈活切換。當版本更新或者活動上線時,可能需要對已有的界面組件在功能保持不變的情況下,對配色布局進行替換。這就需要我們通過抽象層來講它與客戶端代碼解耦。
- 跨平臺網絡庫:游戲引擎需要對不同系統的網絡接口提供抽象與兼容。
再來看抽象工廠的優缺點
- 優點:更多維度的可定制化,可以針對不同的產品變種提供具體的創建邏輯。
- 缺點:更多的類,代碼更多,抽象和理解的過程更加復雜。
- 抽象工廠下的產品通常是協同工作的!