1.简单工厂模式
1.1 定义
定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
1.2 优点
- 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责。
- 客户端无需知道所创建具体产品的类名,只需知道参数即可。
也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
1.3 缺点
工厂类集中了所有产品的创建逻辑,职责过重,一旦异常,整个系统将受影响。
- 使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度。
- 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂。
简单工厂模式使用了static工厂方法,造成工厂角色无法形成基于继承的等级结构。
1.4 使用场景
工厂类负责创建对的对象比较少,因为不会造成工厂方法中的业务逻辑过于复杂。
- 客户端只知道传入工厂类的参数,对如何创建对象不关心。
1.5 类图及示例代码
```cpp // 简单工厂模式
include
using namespace std;
// 怪物父类 class Monster { public: Monster(int life, int magic, int attack) : E_life(life) , E_magic(magic) , E_attack(attack) { } // 做父类时析构函数应该为虚函数 virtual ~Monster() = default;
private: // 怪物属性 int E_life; // 生命值 int E_magic; // 魔法 int E_attack; // 攻击力 };
// 亡灵类怪物 class Undead : public Monster { public: Undead(int life, int magic, int attack) : Monster(life, magic, attack) { cout << “A undead monster came into the world.” << endl; } // 其它逻辑代码 ~Undead() override = default; };
// 元素类怪物 class Element : public Monster { public: Element(int life, int magic, int attack) : Monster(life, magic, attack) { cout << “A element monster came into the world.” << endl; } // 其它逻辑代码 ~Element() override = default; };
// 机械类怪物 class Mechanic : public Monster { public: Mechanic(int life, int magic, int attack) : Monster(life, magic, attack) { cout << “A mechanic monster came into the world.” << endl; } // 其他逻辑代码 ~Mechanic() override = default; };
// 静态工厂 class StaticMonsterFactory { public: enum MonsterType { E_Undead, E_Element, E_Mechanic };
static Monster* CreateMonster(MonsterType type){Monster* monster = nullptr;if (type == E_Undead) { // 亡灵类monster = new Undead(300, 50, 60);} else if (type == E_Element) { // 元素类monster = new Element(200, 80, 100);} else if (type == E_Mechanic) { // 机械类monster = new Mechanic(400, 0, 110);}return monster;}
};
void simple_factory() { std::cout << “simple factory” << std::endl; { // 不创建 Monster monster1 = new Undead(300, 50, 80); Monster monster2 = new Element(200, 50, 100); Monster* monster3 = new Mechanic(400, 0, 110);
delete monster1;delete monster2;delete monster3;}{ // 使用工厂类Monster* monster1 = StaticMonsterFactory::CreateMonster(StaticMonsterFactory::E_Undead);Monster* monster2 = StaticMonsterFactory::CreateMonster(StaticMonsterFactory::E_Element);Monster* monster3 = StaticMonsterFactory::CreateMonster(StaticMonsterFactory::E_Mechanic);delete monster1;delete monster2;delete monster3;}
}
<a name="fTji8"></a>### 2.工厂模式<a name="rMk3a"></a>#### 2.1 定义定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。<a name="ZaWPw"></a>#### 2.2 优点1. 一个调用者想创建一个对象,只要知道其名称就可以了。1. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。1. 屏蔽产品的具体实现,调用者只关心产品的接口。<a name="g7CYM"></a>#### 2.3 缺点每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。<a name="fj9JR"></a>#### 2.4 使用场景1. 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。1. 数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。1. 设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。<a name="oW6y3"></a>#### 2.5 类图及示例代码```cpp// 怪物父类class Monster {public:Monster(int life, int magic, int attack): m_life(life), m_magic(magic), m_attack(attack){}// 做父类时析构函数应该为虚函数virtual ~Monster() = default;protected:int m_life; // 生命值int m_magic; // 魔法值int m_attack; // 攻击力};// 亡灵类怪物class Undead : public Monster {public:Undead(int life, int magic, int attack): Monster(life, magic, attack){cout << "A undead monster came into the world." << endl;}// 其他代码略...~Undead() override = default;};// 元素类怪物class Element : public Monster {public:Element(int life, int magic, int attack): Monster(life, magic, attack){cout << "A element monster came into the world." << endl;}// 其他代码略...~Element() override = default;};// 机械类怪物class Mechanic : public Monster {public:Mechanic(int life, int magic, int attack): Monster(life, magic, attack){cout << "A mechanic monster came into the world." << endl;}// 其他代码略...~Mechanic() override = default;};// 怪物工厂父类class MonsterFactory {public:virtual Monster* CreateMonster() = 0;virtual ~MonsterFactory() = default;};// 亡灵类工厂类class UndeadFactor : public MonsterFactory {public:Monster* CreateMonster() override{// 创建亡灵类怪物return new Undead(300, 50, 80);}};// 元素类工厂类class ElementFactor : public MonsterFactory {public:Monster* CreateMonster() override{// 创建元素类怪物return new Element(300, 50, 80);}};// 机械类工厂类class MechanicFactor : public MonsterFactory {public:Monster* CreateMonster() override{// 创建机械类怪物Monster* temp = new Mechanic(300, 50, 80);return temp;}};// 1.全局的用于创建怪物对象的函数,注意形参的类型是工厂父类类型的指针Monster* globalCreateMonster(MonsterFactory* factory){// 该虚函数扮演了多态new的行为,factory指向的具体怪物工厂类不同,创建的怪物对象也不同return factory->CreateMonster();}// 2.封装工厂子类模板template <typename T>class ChildFactory : public MonsterFactory {public:Monster* CreateMonster() override{return new T(300, 50, 80);}};void FactoryMethod(){{// 产生亡灵类怪物MonsterFactory* undeadFactor = new UndeadFactor();Monster* undead = globalCreateMonster(undeadFactor);// 产生元素类怪物MonsterFactory* elementFactor = new ElementFactor();Monster* element = globalCreateMonster(elementFactor);// 产生机械类怪物MonsterFactory* mechanicFactor = new MechanicFactor();Monster* mechanic = globalCreateMonster(mechanicFactor);delete undeadFactor;delete undead;delete elementFactor;delete element;delete mechanicFactor;delete mechanic;}{// 封装怪物子类ChildFactory<Undead> undeadFactory;Monster* undead = undeadFactory.CreateMonster();delete undead;}}
3.抽象工厂模式
3.1 定义
- 抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
- 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。
- 抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
- 根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
3.2 优点
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。3.3 缺点
产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。3.4 使用场景
#include <iostream>using namespace std;// 怪物父类class Monster {public:Monster(int life, int magic, int attack): m_life(life), m_magic(magic), m_attack(attack){}// 做父类时析构函数应该为虚函数virtual ~Monster() = default;protected:int m_life; // 生命值int m_magic; // 魔法值int m_attack; // 攻击力};// 沼泽地区亡灵类怪物class SwampUndead : public Monster {public:SwampUndead(int life, int magic, int attack): Monster(life, magic, attack){cout << "A swamp undead monster came into the world." << endl;}// 其他代码略...~SwampUndead() override = default;};// 沼泽地区元素类怪物class SwampElement : public Monster {public:SwampElement(int life, int magic, int attack): Monster(life, magic, attack){cout << "A swamp element monster came into the world." << endl;}// 其他代码略...~SwampElement() override = default;};// 沼泽地区机械类怪物class SwampMechanic : public Monster {public:SwampMechanic(int life, int magic, int attack): Monster(life, magic, attack){cout << "A swamp mechanic monster came into the world." << endl;}// 其他代码略...~SwampMechanic() override = default;};// 山脉亡灵类怪物class MountainUndead : public Monster {public:MountainUndead(int life, int magic, int attack): Monster(life, magic, attack){cout << "A mountain undead monster came into the world." << endl;}// 其他代码略...~MountainUndead() override = default;};// 山脉元素类怪物class MountainElement : public Monster {public:MountainElement(int life, int magic, int attack): Monster(life, magic, attack){cout << "A mountain element monster came into the world." << endl;}// 其他代码略...~MountainElement() override = default;};// 山脉机械类怪物class MountainMechanic : public Monster {public:MountainMechanic(int life, int magic, int attack): Monster(life, magic, attack){cout << "A mountain mechanic monster came into the world." << endl;}// 其他代码略...~MountainMechanic() override = default;};// 城镇亡灵类怪物class TownUndead : public Monster {public:TownUndead(int life, int magic, int attack): Monster(life, magic, attack){cout << "A town undead monster came into the world." << endl;}// 其他代码略...~TownUndead() override = default;};// 山脉元素类怪物class TownElement : public Monster {public:TownElement(int life, int magic, int attack): Monster(life, magic, attack){cout << "A town element monster came into the world." << endl;}// 其他代码略...~TownElement() override = default;};// 山脉机械类怪物class TownMechanic : public Monster {public:TownMechanic(int life, int magic, int attack): Monster(life, magic, attack){cout << "A town mechanic monster came into the world." << endl;}// 其他代码略...~TownMechanic() override = default;};// 所有工厂类的父类class MonsterFactory {public:// 创建亡灵类怪物virtual Monster* createMonsterUndead() = 0;// 创建元素类怪物virtual Monster* createMonsterElement() = 0;// 创建机械类怪物virtual Monster* createMonsterMechanic() = 0;// 做父类时析构函数应该为虚函数virtual ~MonsterFactory() = default;};// 沼泽地区工厂类class SwapFactory : public MonsterFactory {public:// 创建沼泽地区亡灵类怪物Monster* createMonsterUndead() override{return new SwampUndead(300, 50, 120);};// 创建沼泽地区元素类怪物Monster* createMonsterElement() override{return new SwampElement(200, 80, 110);};// 创建沼泽地区机械类怪物Monster* createMonsterMechanic() override{return new SwampMechanic(400, 0, 90);};~SwapFactory() override = default;};// 山脉地区工厂类class MountainFactory : public MonsterFactory {public:// 创建山脉地区亡灵类怪物Monster* createMonsterUndead() override{return new MountainUndead(300, 50, 80);};// 创建山脉地区元素类怪物Monster* createMonsterElement() override{return new MountainElement(200, 80, 100);};// 创建山脉地区机械类怪物Monster* createMonsterMechanic() override{return new MountainMechanic(600, 0, 90);};~MountainFactory() override = default;};// 城镇地区工厂类class TownFactory : public MonsterFactory {public:// 创建城镇地区亡灵类怪物Monster* createMonsterUndead() override{return new TownUndead(300, 50, 120);};// 创建城镇地区元素类怪物Monster* createMonsterElement() override{return new TownElement(200, 80, 110);};// 创建城镇地区机械类怪物Monster* createMonsterMechanic() override{return new TownMechanic(400, 0, 90);};~TownFactory() override = default;};void AbstractFactory(){// 多态工厂, 山脉地区的工厂MonsterFactory* mountainFactory = new MountainFactory();// 创建山脉地区的元素类怪物、亡灵类怪物Monster* mountainElementMonster = mountainFactory->createMonsterElement();Monster* mountainUndeadMonster = mountainFactory->createMonsterUndead();// 多态工厂,沼泽地区的工厂MonsterFactory* swampFactory = new SwapFactory();// 创建山脉地区的元素类怪物、亡灵类怪物Monster* swampElementMonster = swampFactory->createMonsterElement();Monster* swampUndeadMonster = swampFactory->createMonsterUndead();delete mountainFactory;delete mountainElementMonster;delete mountainUndeadMonster;delete swampFactory;delete swampElementMonster;delete swampUndeadMonster;}

