欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 【设计模式】工厂模式

【设计模式】工厂模式

2025/1/30 13:26:22 来源:https://blog.csdn.net/Siro_sama/article/details/142062485  浏览:    关键词:【设计模式】工厂模式

设计模式共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();}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com