享元模式
为了避免产生过多的临时对象,创建一个对象,需要不同对象的时候设置不同的参数。享元就是共享元素,以共享的方式来避免大量拥有相同内容对象的开销。对于经常使用且仅参数不同的对象,不是每次都重新创建一个不同的对象,而是创建一个对象之后,每次使用时传入不同的参数。
享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关 键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部,不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能 影响内蕴状态,它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。客户 端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。
#include <iostream>
#include <map>
using namespace std;
class Person{
public:
Person(string name, int age){
m_name = name;
m_age = age;
}
void setName(string name)
{
this->m_name = name;
}
virtual ~Person(){}
virtual void showInfo()=0;
protected:
string m_name;
int m_age;
};
class Teacher : public Person{
public:
Teacher(string id, string name, int age):Person(name, age){
m_id = id;
}
void showInfo(){
std::cout << "name:" <<m_name<< std::endl;
std::cout << "age:" <<m_age<< std::endl;
std::cout << "id:" <<m_id<< std::endl;
}
private:
string m_id;
};
class FlyweightFactory{
public:
FlyweightFactory(){
m_map.clear();
}
~FlyweightFactory(){
while(!m_map.empty()){
map<string, Person *>::iterator it = m_map.begin();
Person *p = it->second;
m_map.erase(it);
delete p;
}
}
Person* getTeacher(string id){
map<string, Person *>::iterator it = m_map.find(id);
if(it==m_map.end()){
Teacher *tmp = new Teacher(id, "default", 0);
m_map.insert(pair<string, Person *>(id, tmp));
return tmp;
}
return it->second;
}
private:
map<string, Person *> m_map;
};
int main()
{
FlyweightFactory *fac = new FlyweightFactory();
Person *p1=fac->getTeacher("001");
p1->showInfo();
Person *p2 = fac->getTeacher("001");
p2->showInfo();
std::cout <<p1<<" : "<<p2<< std::endl;
p2->setName("Peter");
p1->showInfo();
p2->showInfo();
delete fac;
return 0;
}