注册工厂模式
作用及特点:拓展性强,方便增加产品类,每次增加一个产品,将创建该产品的函数指针,注册到管理类中,调用工厂类的创建接口,即可返回对应的产品, 一般来说将工厂类作为管理类,产品类作为返回对象。
声明动物类
接下来我们用马戏团的动物来举例,将所有的动物表演动作,作为我们想要执行的函数动作
这里我们将动物园的所有动物抽象成 Animal,再将 Animal 分为陆地动物 TerrestrialAnimal ,水生动物 AquaticAnimals ,鸟类 FlyingBird
接下来是Animal.h和Animal.cpp的详细代码
Animal.h
#pragma once
#include<iostream>
class Animal
{
public:
virtual ~Animal();
virtual bool init(const std::string& name);
protected:
std::string m_name;
int m_age;
std::string m_sex;
};
class TerrestrialAnimal :public Animal
{
public:
virtual void running() = 0;
protected:
int m_weight;//体重为多少
};
class AquaticAnimal :public Animal
{
public:
virtual void swimming() = 0;
protected:
bool m_FreshwaterFish;//是否为淡水
};
class FlyingBird :public Animal
{
public:
virtual void flying() = 0;
protected:
int m_canFly;//是否会飞
};
class Tiger :public TerrestrialAnimal//老虎类
{
public:
Tiger(const std::string& name);
~Tiger();
virtual bool init(const std::string& name);
virtual void running();
static Tiger* New(const std::string& name);
};
class Eagle :public FlyingBird//老鹰类
{
public:
Eagle(const std::string& name);
~Eagle();
virtual bool init(const std::string& name);
virtual void flying();
static Eagle* New(const std::string& name);
};
Animal.cpp
#include "Animal.h"
#include "AnimalManager.h"
Animal* CreateTiger(const std::string& name) { return Tiger::New(name); }
Animal* CreateEagle(const std::string& name) { return Eagle::New(name); }
static bool s = GetAnimalManager()->registerAnimal({ "Tiger", "TerrestrialAnimal ", CreateTiger });
static bool t = GetAnimalManager()->registerAnimal({ "Eagle", "FlyingBird ", CreateEagle });
Animal::~Animal()
{
printf("动物类析构~~~~~~\n\n");
}
bool Animal::init(const std::string& name)
{
m_name = name;
return true;
}
Tiger* Tiger::New(const std::string& name)
{
return new Tiger(name);
}
Tiger::Tiger(const std::string& name)
{
init(name);
}
Tiger::~Tiger()
{
printf("老虎类析构~~~~~~\n");
}
bool Tiger::init(const std::string& name)
{
if (!Animal::init(name))
{
return false;
}
printf("虎虎生威,我是%s,闪亮登场!\n\n", m_name.c_str());
return true;
}
void Tiger::running()
{
printf("我是%s,我正在奔跑!\n\n", m_name.c_str());
}
Eagle* Eagle::New(const std::string& name)
{
return new Eagle(name);
}
Eagle::Eagle(const std::string& name)
{
init(name);
}
Eagle::~Eagle()
{
printf("老鹰类析构~~~~~~\n");
}
bool Eagle::init(const std::string& name)
{
if (!Animal::init(name))
{
return false;
}
printf("鹰击长空,我是%s,闪亮登场!\n\n", m_name.c_str());
return true;
}
void Eagle::flying()
{
printf("我是%s,我正在飞翔!\n\n", m_name.c_str());
}
声明马戏团管理员类
工厂类就是马戏团管理员, 我们在马戏团管理员那登记过的动物,都把它们记录在m_animalFactory,我们创建出来的所有动物都存放在m_StageOfAnimal,我们可以根据名称找到它
接下来是AnimalManager.h和AnimalManager.cpp的详细代码
AnimalManager.h
#pragma once
#include <iostream>
#include<unordered_map>
#include"Animal.h"
using createFunction = Animal* (*)(const std::string& name);//声明函数指针
struct AnimalInfo
{
std::string AnimalName; //动物名称,例如老虎,老鹰
std::string AnimalType; //动物类型,水生动物,飞行动物
createFunction createFunc;//函数指针
};
class AnimalManager
{
public:
void callAnimal(const std::string& type, const std::string& name);//叫动物出来
Animal* findAnimal(const std::string& name);//通过名称找到场上的动物
void exit(const std::string& name);//让动物下场
bool registerAnimal(const AnimalInfo& animalInfo);//动物在管理员登记
private:
std::unordered_map<std::string, Animal*> m_stageOfAnimal;//目前上动物
std::unordered_map<std::string, AnimalInfo> m_animalFactory;//已登记的动物列表
};
AnimalManager* GetAnimalManager();
AnimalManager.cpp
#include "AnimalManager.h"
AnimalManager* GetAnimalManager()
{
static AnimalManager s_instance;
return &s_instance;//静态方式得到管理员类
}
void AnimalManager::callAnimal(const std::string& type, const std::string& name)
{
auto iter = m_animalFactory.find(type);
if (iter != m_animalFactory.end())
{
Animal* animal = iter->second.createFunc(name);
m_stageOfAnimal.emplace(std::make_pair(name, animal));
}
}
Animal* AnimalManager::findAnimal(const std::string& name)
{
auto iter = m_stageOfAnimal.find(name);
Animal* animal = nullptr;
if (iter != m_stageOfAnimal.end())
{
animal = iter->second;
}
return animal;//注意如果没有找到会返回空;
}
void AnimalManager::exit(const std::string& name)
{
auto iter = m_stageOfAnimal.find(name);
if (iter != m_stageOfAnimal.end())
{
if (iter->second != nullptr)
{
delete iter->second;
}
m_stageOfAnimal.erase(iter);
}
}
bool AnimalManager::registerAnimal(const AnimalInfo& animalInfo)
{
m_animalFactory.emplace(animalInfo.AnimalName, animalInfo);
return true;
}
马戏团开始表演
假设应用场景:
马戏团管理员,先登记所有马戏团动物,然后依次叫它们上场表演,并将它们的名称记录在本子上,过一段时间叫它们退场,并删除记录
#include "Animal.h"
#include "AnimalManager.h"
int main()
{
GetAnimalManager()->callAnimal("Tiger", "小脑斧");
Tiger* tiger = (Tiger*)GetAnimalManager()->findAnimal("小脑斧");
tiger->running();
GetAnimalManager()->callAnimal("Eagle", "大佬凝");
Eagle* eagle = (Eagle*)GetAnimalManager()->findAnimal("大佬凝");
eagle->flying();
GetAnimalManager()->exit("大佬凝");
GetAnimalManager()->exit("小脑斧");
}
输出结果和总结
- 主函数中无注册产品类操作,产品类易拓展,注册行为发生在静态变量初始化期间
- GetAnimalManager()获取单例工厂指针,随时可以进行创建产品
- 创建的产品存储起来可以随时获取其指针,进行产品特有的操作
- 可以对产品进行删除操作,子类先析构,基类后析构