设计模式共23种,总共分为三大类:创建型模式,结构型模式,行为性模式
工厂模式属于创建型模式,其聚焦于如何组织类去实例化一个对象,实际上就是在原本直接的new的基础上进行一个封装,达到可以方便随时变更,扩展,和其他类交互的功能
文章目录
- 简单工厂
- 工厂模式
- 抽象工厂模式
简单工厂
简单工厂顾名思义,十分简单,基本思想就是创建一个工厂类用来管理某一类对象的实例化,用户只需要实例化一个工厂对象,并传入一个字符串或枚举来确定自己需要的对象,工厂就能自动构造出一个所需的对象,而创建这个对象的所有操作都会集中在工厂内进行,后期需要修改时也无需到处去替换,只需在工厂内修改。
代码定义了一个Unit基类,三种继承其的角色和一个用于创建三种角色的Factory类
从代码也很明显可以看出简单工厂的缺点,就是每次增加一个类,都需要去修改工厂内部的函数,不符合开闭原则,当类过多时也难以修改。当然如果类不多,那么简单工厂就足够使用了,毕竟正如其名,简单工厂
#include <iostream>
using namespace std;namespace SimpleFactory
{
class Unit
{
public:virtual void Call() = 0;
};class Warrior : public Unit
{
public:virtual void Call() override{cout << "I am Warrior!" << endl;}
};class Archer : public Unit
{
public:virtual void Call() override{cout << "I am Archer!" << endl;}
};class Wizard : public Unit
{
public:virtual void Call() override{cout << "I am Wizard!" << endl;}
};namespace EUnit
{enum Type{Warrior,Archer,Wizard};
}//简单工厂(显然不符合开闭原则)
class UnitFactory
{
public:Unit* CreateUnit(EUnit::Type unit){switch(unit){case EUnit::Warrior:return new Warrior();case EUnit::Archer:return new Archer();case EUnit::Wizard:return new Wizard();}return nullptr;}
};
}int main()
{//简单工厂{using namespace SimpleFactory;UnitFactory factory;Unit* warrior = factory.CreateUnit(EUnit::Warrior);Unit* archer = factory.CreateUnit(EUnit::Archer);Unit* wizard = factory.CreateUnit(EUnit::Wizard);warrior->Call();archer->Call();wizard->Call();}
}
工厂模式
工厂模式在简单工厂的基础上,遵循了开闭原则,即对修改关闭,对扩展开放,将增加支持的类的操作从修改函数变成了继承并写新的子类
即工厂模式提供了一个工厂基类,需要一种产品时就创建对应的工厂类
下述代码和简单工厂最大的不同就是创建了一个工厂类的接口,并实现了三种工厂对应三种单位,使用时创建对应的单位来创建所需的对象。
之所以这样看着感觉毫无意义徒增复杂度,是因为这只是最基础的代码框架,在每个子类和父类,和继承链条上的每一处都可以插入其他的函数来扩展创建时的功能,最简单的,如果你需要一个计数器来记录创建的对象数量,那么直接在工厂的父类中创建一个静态变量,或者创建一个专门的计数类,并在工厂中引用这个计数类,在创建时累加。这些都可以轻松做到
#include <iostream>
using namespace std;namespace FactoryPattern
{//通过定义接口进行使用
class IUnit
{
public:virtual void Call() = 0;virtual ~IUnit() {};
};class IFactory
{
public:virtual IUnit* Create() = 0;
};class Warrior : public IUnit
{
public:virtual void Call() override{cout << "I am Warrior!" << endl;}
};class Archer : public IUnit
{
public:virtual void Call() override{cout << "I am Archer!" << endl;}
};class Wizard : public IUnit
{
public:virtual void Call() override{cout << "I am Wizard!" << endl;}
};class WarriorFactory : public IFactory
{
public:virtual IUnit* Create() override{return new Warrior();}
};class ArcherFactory : public IFactory
{
public:virtual IUnit* Create() override{return new Archer();}
};class WizardFactory : public IFactory
{
public:virtual IUnit* Create() override{return new Wizard();}
};}int main()
{//工厂模式{using namespace FactoryPattern;IFactory* factorys[3];factorys[0] = new WarriorFactory();factorys[1] = new ArcherFactory();factorys[2] = new WizardFactory();for(int i = 0; i < 3; i++){IUnit* unit = factorys[i]->Create();unit->Call();delete unit;} }
}
抽象工厂模式
上述工厂类,在使用过程中,因为每个产品类都需要一个对应的工厂类,这样在后期会导致工厂类的数量膨胀,其结果是同样也不好维护,最好的方式是将有类似性质的类组成一组,放在一个工厂中,这样可以十分有效的减少工厂类的数量,同时对于上层用户而言,也无需创建特别多的工厂来创建所需的对象
下面的代码解释:一个接口IEqiupable代表可穿戴的接口,然后由Weapon和Armor两个大类分别继承
接下来再细分两个大类,剑与弓,重甲与轻甲
创建IFactory工厂类接口,工厂能够创建Weapon和Armor两种物品
MeleeFactory近战工厂生产的是剑和重甲
RemoteFactory远程工厂生产的是弓和轻甲
#include <iostream>
using namespace std;namespace AbstractFactory
{class IEqiupable{public:virtual void Show() = 0;virtual ~IEqiupable() {};};class Weapon : public IEqiupable{public:virtual void Show() override{cout << "武器:" << GetName() << "\t";};protected:virtual string GetName() = 0;};class Sword : public Weapon{virtual string GetName() override{return "剑";}};class Bow : public Weapon{virtual string GetName() override{return "弓";}};class Armor : public IEqiupable{public:virtual void Show() override{cout << "防具:" << GetName();};protected:virtual string GetName() = 0;};class LightArmor : public Armor{virtual string GetName() override{return "轻甲";}};class HeavyArmor : public Armor{virtual string GetName() override{return "重甲";}};class IFactory{public:virtual Weapon* CreateWeapon() = 0;virtual Armor* CreateArmor() = 0;};class MeleeFactory : public IFactory{public:virtual Weapon* CreateWeapon() override{return new Sword();}virtual Armor* CreateArmor() override{return new HeavyArmor();}};class RemoteFactory : public IFactory{public:virtual Weapon* CreateWeapon() override{return new Bow();}virtual Armor* CreateArmor() override{return new LightArmor();}};
}int main()
{//抽象工厂模式{using namespace AbstractFactory;MeleeFactory meleeFacotory;Weapon* weapon = meleeFacotory.CreateWeapon();Armor* armor = meleeFacotory.CreateArmor();weapon->Show();armor->Show();cout << endl;delete weapon;delete armor;RemoteFactory remoteFactory;weapon = remoteFactory.CreateWeapon();armor = remoteFactory.CreateArmor();weapon->Show();armor->Show();}
}