设计模式 结构性模式 享元模式
享元模式
以共享的方式高效支持大量细密度对象的重用,关键是区分了内部状态
和外部状态
,内部状态可以共享,外部状态通过方法传递进来,而不是作为对象的 data member.
不同棋子可以落在不同的位置
,这个是外部状态.
内部状态,可以共享,不用每颗棋子都去存一个黑色白色
的属性.
外部状态,可以 setter 方式注入到享元对象中.
内部状态保存在享元池里,如 HashMap,访问享元池时,存在的直接返回,不存在则 new 一个,可以结合单例模式,工厂模式这些创建者模式使用.
#include <iostream>
#include <map>
#include <string>
// 棋子享元, 有内部数据, 提供访问内部方法, 无外部数据, 仅提供抽象方法
class Qizi {
public:
Qizi(std::string n) :color(std::move(n)) {}
virtual ~Qizi() = default;
//获取内部状态的方法,
std::string getColor() {return color;}
//设置外部状态的方法
virtual int setPos(int x, int y) {}
virtual int setIdx(int idx) {}
private:
const std::string & color;
};
//具体实现了外部状态如何处理的享元
class ConcreteQizi : public Qizi {
public:
ConcreteQizi(std::string n): Qizi(std::move(n)) {}
//virtual ~ConcreteQizi(){};
int setPos(int x, int y) {
std::cout << "pos:" << x << "," << y << std::endl;
return 0;
}
int setIdx(int idx) {
std::cout << "idx:" << idx << std::endl;
return 0;
}
};
//享元工厂+单例
class QiziFactory {
public:
ConcreteQizi getQizi(std::string color) {
if( m_qizi.find(color) == m_qizi.end()) {
std::cout << "create " << color << "qizi" << std::endl;
m_qizi.emplace(color,ConcreteQizi(color));
} else {
std::cout << "already have " << color << "qizi" << std::endl;
}
return m_qizi.at(color);
}
//简单单例
static QiziFactory* getInstance(void) {
if (qiziFactory == NULL) {
qiziFactory = new QiziFactory();
}
return qiziFactory;
}
private:
std::map<std::string,ConcreteQizi> m_qizi;
static QiziFactory * qiziFactory;
};
QiziFactory * QiziFactory::qiziFactory = NULL;
/**
* @brief main
* @param argc
* @param argv[]
* @return
*/
int main(int argc , char* argv[])
{
auto qiziFactory = QiziFactory::getInstance();
auto black = qiziFactory->getQizi("black");
black.setIdx(0);
black.setPos(1,3);
auto white = qiziFactory->getQizi("white");
white.setIdx(1);
white.setPos(2,2);
auto black1 = qiziFactory->getQizi("black");
black1.setIdx(2);
black1.setPos(3,3);
auto white1 = qiziFactory->getQizi("white");
white1.setIdx(3);
white1.setPos(4,2);
return 0;
}
结果:
create blackqizi
idx:0
pos:1,3
create whiteqizi
idx:1
pos:2,2
already have blackqizi
idx:2
pos:3,3
already have whiteqizi
idx:3
pos:4,2