设计模式(C++实现)(二十三)——享元模式

示例问题:

一个制造杯子的厂商,主要生产大、中、小圆柱形杯子(这3种规格的杯子上印有各种各样的文字),以及特殊造型杯子1,特殊造型杯子2。现需要定制模具来生产杯子,用代码解决该问题。

分析:

由于大、中、小圆柱形杯子上印有成千上万种文字,不可能为印有每一种文字的杯子都制造一个模具。只有制造好了大、中、小杯子的模具,之后能够灵活在上面印刷文字,才是上上策。

解决方案:

Flyweight.h

在该文件中实现了杯子的基类CCup,及其子类CSmallCup(小杯子)、CMediumCup(中杯子)、CBigCup(大杯子)、CSpecialCup1(特殊造型杯子1)、CSpecialCup2(特殊造型杯子2)。其中CSmallCup、CMediumCup、CBigCup由于可以自由印刷文件,为共享的类;CSpecialCup1、CSpecialCup2独特,为不共享的类。

#pragma once

#include <iostream>
#include <string>
#include <map>

//杯子种类
enum CupType
{
	SMALLCUP = 0,
	MEDIUMCUP = 1,
	BIGCUP = 2,
	SPECIALCUP1 = 3,
	SPECIALCUP2 = 4
};

//杯子基类
class CCup
{
public:
	CCup()
	{

	}

	virtual ~CCup()
	{

	}

	//水杯必备功能:装水
	void TakeInWater()
	{
		std::cout << "用来装水" << std::endl;
	}

	//添加文字
	virtual void AddText(std::string strText) = 0;

	//展示杯子
	virtual void Show() = 0;

	std::string m_strText;
};

//小杯子
class CSmallCup : public CCup
{
public:
	CSmallCup()
	{

	}

	virtual ~CSmallCup()
	{

	}

	void AddText(std::string strText)
	{
		m_strText = strText;
	}

	void Show()
	{
		std::cout << "小杯子(" << m_strText << ")" << std::endl;
	}
};

//中杯子
class CMediumCup : public CCup
{
public:
	CMediumCup()
	{

	}

	virtual ~CMediumCup()
	{

	}

	void AddText(std::string strText)
	{
		m_strText = strText;
	}

	void Show()
	{
		std::cout << "中杯子(" << m_strText << ")" << std::endl;
	}
};

//大杯子
class CBigCup : public CCup
{
public:
	CBigCup()
	{

	}

	virtual ~CBigCup()
	{

	}

	void AddText(std::string strText)
	{
		m_strText = strText;
	}

	void Show()
	{
		std::cout << "大杯子(" << m_strText << ")" << std::endl;
	}
};

//特殊造型杯子1
class CSpecialCup1 : public CCup
{
public:
	CSpecialCup1()
	{

	}

	virtual ~CSpecialCup1()
	{

	}

	void AddText(std::string strText)
	{

	}

	void Show()
	{
		std::cout << "特殊造型杯子1"<< std::endl;
	}
};

//特殊造型杯子2
class CSpecialCup2 : public CCup
{
public:
	CSpecialCup2()
	{

	}

	virtual ~CSpecialCup2()
	{

	}

	void AddText(std::string strText)
	{

	}

	void Show()
	{
		std::cout << "特殊造型杯子2" << std::endl;
	}
};

//杯子工厂(生产杯子)
class CCupFactory
{
public:
	CCupFactory()
	{
		
	}

	virtual ~CCupFactory()
	{
		for (auto itor : m_mapCup)
		{
			if (nullptr != itor.second)
			{
				delete itor.second;
				itor.second = nullptr;
			}
		}
	}

	CCup* CreatCup(CupType iCupType, std::string strText)
	{
		CCup* pCup = m_mapCup[iCupType];
		switch (iCupType)
		{
		case SMALLCUP:
			{
				if (nullptr == pCup)
				{
					pCup = new(std::nothrow) CSmallCup();
					if (nullptr != pCup)
					{
						m_mapCup[iCupType] = pCup;
						pCup->AddText(strText);
					}
				}
				else
				{
					pCup->AddText(strText);
				}
			}
			break;
		case MEDIUMCUP:
			{
				if (nullptr == pCup)
				{
					pCup = new(std::nothrow) CMediumCup();
					if (nullptr != pCup)
					{
						m_mapCup[iCupType] = pCup;
						pCup->AddText(strText);
					}
				}
				else
				{
					pCup->AddText(strText);
				}
			}
			break;
		case BIGCUP:
			{
				if (nullptr == pCup)
				{
					pCup = new(std::nothrow) CBigCup();
					if (nullptr != pCup)
					{
						m_mapCup[iCupType] = pCup;
						pCup->AddText(strText);
					}
				}
				else
				{
					pCup->AddText(strText);
				}
			}
			break;
		case SPECIALCUP1:
			{
				if (nullptr == pCup)
				{
					pCup = new(std::nothrow) CSpecialCup1();
					if (nullptr != pCup)
					{
						m_mapCup[iCupType] = pCup;
					}
				}
			}
			break;
		case SPECIALCUP2:
			{
				if (nullptr == pCup)
				{
					pCup = new(std::nothrow) CSpecialCup2();
					if (nullptr != pCup)
					{
						m_mapCup[iCupType] = pCup;
					}
				}
			}
			break;
		default:
			break;
		}
		return pCup;
	}

private:
	std::map<CupType, CCup*> m_mapCup;
};

main.cpp

// main.cpp : Defines the entry point for the console application.
//

#include "Flyweight.h"

int main()
{
	CCupFactory CupFactory;
	//生产小杯子
	{
		CCup* pCup = CupFactory.CreatCup(SMALLCUP, "富强");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(SMALLCUP, "民主");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(SMALLCUP, "文明");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(SMALLCUP, "和谐");
		pCup->Show();
	}

	//生产中杯子
	{
		CCup* pCup = CupFactory.CreatCup(MEDIUMCUP, "自由");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(MEDIUMCUP, "平等");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(MEDIUMCUP, "公正");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(MEDIUMCUP, "法治");
		pCup->Show();
	}

	//生产大杯子
	{
		CCup* pCup = CupFactory.CreatCup(BIGCUP, "爱国");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(BIGCUP, "敬业");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(BIGCUP, "诚信");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(BIGCUP, "友善");
		pCup->Show();
	}
	
	//生产特殊造型杯子1
	{
		CCup* pCup = CupFactory.CreatCup(SPECIALCUP1, "");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(SPECIALCUP1, "");
		pCup->Show();
	}

	//生产特殊造型杯子2
	{
		CCup* pCup = CupFactory.CreatCup(SPECIALCUP2, "");
		pCup->Show();
	}
	{
		CCup* pCup = CupFactory.CreatCup(SPECIALCUP2, "");
		pCup->Show();
	}

	system("pause");
    return 0;
}

运行结果

享元模式的使用:

享元模式:运用共享技术有效的支持大量细粒度的对象,来提高应用程序的性能,节约系统中重复创建对象实例的性能消耗。

享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据,如果能发现这些实例除了几个参数外基本上都相同,那就可以用享元模式,把那么参数移到类实例的外面,在方法调用时将它们传递进来,从而通过共享减少需要实例化的数量

何时使用享元模式:

如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;还有就是对象的大多数状态可以为外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

 

返回目录:设计模式(C++实现)(总)

上一篇:设计模式(C++实现)(二十二)——中介者模式

下一篇:设计模式(C++实现)(二十四)——解释器模式

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值