需求分析:创建大量相同或相似对象实例的问题。如围棋和五子棋中的黑白棋子,局域网中的路由器、交换机和集线器等。
享元模式:通过共享已经存在的来大幅度减少需要创建的对象数量、避免大量相似类的开销。
优点:相同对象只要保存一份,降低了系统中对象的数量。
缺点:
- 为了使对象可以共享,需要将一些不能共享的状态外部化,这增加复杂性。
- 读取外部状态会使得运行时间稍微变长。
主要角色:
- 抽象享元角色: 是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
- 具体享元角色:实现抽象享元角色中所规定的接口。
- 非享元角色:不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
- 享元工厂角色:负责创建和管理享元角色。
具体案例:
小码路接到公司一个任务,最近网络不太稳定,想查看一下公司路由器和交换机的个数,并把链接的终端数目也找出来,看看是不是有人在破坏!
第一步:抽象享元角色
代码语言:javascript复制#pragma once
#include <iostream>
using namespace std;
#include <map>
#include <string>
#include <future>
#include <thread>
//抽象享元类
class NetDevice
{
public:
virtual string deviceKind()=0;
virtual void link()=0;
};
第二步:具体享元角色
代码语言:javascript复制//具体享元类
//包括交换机,路由器等
class LuYouQi:public NetDevice
{
public:
LuYouQi(string kind)
{
this->kind=kind;
}
string deviceKind()
{
return this->kind;
}
void link()
{
cout<<"连接了型号为:"<<this->kind<<" 的路由器!"<<endl;
}
private:
string kind;
};
class JiaoHuanJi:public NetDevice
{
public:
JiaoHuanJi(string kind)
{
this->kind=kind;
}
string deviceKind()
{
return this->kind;
}
void link()
{
cout<<"连接了型号为: "<<this->kind<<" 的交换机!"<<endl;
}
private:
string kind;
};
第三步:享元工厂角色
代码语言:javascript复制//享元工厂类
class DeviceFactory
{
public:
DeviceFactory()
{
shared_ptr<NetDevice> d1=make_shared<LuYouQi>("TP-Link-01");
devices.insert(make_pair("Tp",d1));
shared_ptr<NetDevice> d2=make_shared<JiaoHuanJi>("思科01");
devices.insert(make_pair("Cis",d2));
}
shared_ptr<NetDevice> getNetDevice(string kind)
{
if(devices.count(kind))
{
count ;
return devices.find(kind)->second;
}
else
{
return nullptr;
}
}
int getTotalDevice()
{
return devices.size();
}
int getTerminalCount()
{
return count;
}
private:
map<string,shared_ptr<NetDevice> > devices;
int count=0;
};
第四步:客户端
代码语言:javascript复制#include "n.h"
int main()
{
shared_ptr<NetDevice> d1,d2,d3,d4;
shared_ptr<DeviceFactory> df=make_shared<DeviceFactory>();
d1=df->getNetDevice("Cis");
d1->link();
d2=df->getNetDevice("Cis");
d2->link();
d3=df->getNetDevice("Tp");
d3->link();
d4=df->getNetDevice("Tp");
d4->link();
cout<<"设备总数:"<<df->getTotalDevice()<<endl;
cout<<"终端总数:"<<df->getTerminalCount()<<endl;
return 0;
}
结果显示: