注册工厂模式

注册工厂模式

  作用及特点:拓展性强,方便增加产品类,每次增加一个产品,将创建该产品的函数指针,注册到管理类中,调用工厂类的创建接口,即可返回对应的产品, 一般来说将工厂类作为管理类,产品类作为返回对象。

声明动物类

  接下来我们用马戏团的动物来举例,将所有的动物表演动作,作为我们想要执行的函数动作
这里我们将动物园的所有动物抽象成 Animal,再将 Animal 分为陆地动物 TerrestrialAnimal ,水生动物 AquaticAnimals ,鸟类 FlyingBird

Animal
#int m_age
#string m_sex
#bool m_sick
virtual void init()
TerrestrialAnimal
#int m_weight
+virtual void running()
AquaticAnimal
#bool m_canFly
+virtual void swimming()
FlyingBird
#bool m_FreshwaterFish
+virtual void flying()

接下来是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
-unordered_map<string,Animal*> m_stageOfAnimal
-unordered_map<string,Animal*>m_animalFactory
+callAnimal(string type, string name)
+Animal* findAnimal(string name)
+exit(string name)
+registerAnimal(AnimalInfo animalInfo)

接下来是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()获取单例工厂指针,随时可以进行创建产品
  • 创建的产品存储起来可以随时获取其指针,进行产品特有的操作
  • 可以对产品进行删除操作,子类先析构,基类后析构

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值