简介
用于减少创建对象的数量,实现对象的共享,当对象多的时候可以减少内存占用和提高性能。
角色与职责
- Flyweight:描述一个接口,通过这个接口flyweight可以接受并作用于外部状态;
- ConcreteFlyweight:实现Flyweight接口,并为定义了一些内部状态,ConcreteFlyweight对象必须是可共享的;同时,它所存储的状态必须是内部的;即,它必须独立于ConcreteFlyweight对象的场景;
- UnsharedConcreteFlyweight:并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。所以此类可以没有。
- FlyweightFactory:创建并管理flyweight对象。它需要确保合理地共享flyweight;当用户请求一个flyweight时,FlyweightFactory对象提供一个已创建的实例,如果请求的实例不存在的情况下,就新创建一个实例;
- Client:维持一个对flyweight的引用;同时,它需要计算或存储flyweight的外部状态。
实现
#include <iostream>
#include <string>
#include <map>
using namespace std;
// 对应Flyweight
class Person {
public:
Person(string name, int age) : m_name(name), m_age(age){}
virtual void printT() = 0;
protected:
string m_name;
int m_age;
};
// 对应ConcreteFlyweight
class Teacher : public Person {
public:
Teacher(string name, int age, string id) :Person(name, age), m_id(id) {}
virtual void printT() {
cout << "name:" << m_name << " age:" << m_age << " id:" << m_id << endl;
}
private:
string m_id;
};
// 对应FlyweightFactory
class FlyweightTeacherFactory {
public:
FlyweightTeacherFactory() {
m_map.clear();
}
~FlyweightTeacherFactory() {
while (!m_map.empty()) {
Person* tmp = NULL;
map<string, Person*>::iterator it = m_map.begin();
tmp = it->second;
m_map.erase(it);
delete tmp;
}
}
Person* getTeacher(string id) {
map<string, Person*>::iterator it = m_map.find(id);
if (it == m_map.end()) {
string t_name;
int t_age = 0;
cout << "input teacher name, please!" << endl;
cin >> t_name;
cout << "input teacher age, please!" << endl;
cin >> t_age;
Person* temp = new Teacher(t_name, t_age, id);
m_map.insert(pair<string, Person*>(id, temp));
return temp;
}
else {
return it->second;
}
}
private:
map<string, Person*> m_map;
};
int main(int argc, char* argv[]) {
Person *p1 = NULL;
Person *p2 = NULL;
FlyweightTeacherFactory* fwtf = new FlyweightTeacherFactory;
p1 = fwtf->getTeacher("001");
p1->printT();
p2 = fwtf->getTeacher("001");
p2->printT();
cin.get();
return 0;
}