31.2 对象池模式
31.2.1 定义和类图
(1)定义:对象池是一种设计模式,它通过管理有限对象复用来共享某些稀少或必须付出昂贵代价的资源。
(2)类图:
31.2.2 对象池的扩展接口
(1)两级对象池方式:空闲对象池和已用对象池
(2)利用Wrapper模式包装复用对象,使附加一些属性(如空闲时间)
class wrapper { private: int useTime; //开始使用时间 int unuseTime; //开始空闲时间 //其他附加属性 Object* reusable; //复用对象的指针 };
(3)空闲对象池:存放目前还没有分配出去的空闲复用对象
①wrapper* get(string model, string strategy);//获得一个空闲对象(这里的策略指分配空闲对象的策略,如最大空闲时间分配或随机分配等)
②void add(string model, wrapper* object);//加入一个空闲对象
(4)己用对象池:存放正在被客户端使用的连接。
①void close(wrapper* object); //将对象从己用对象池中删除
②void put(wrapper* object); //加入一个复用对象
31.2.3 复用对象的建立和消亡
(1)复用对象创建: wrapper* create(string model);//注意是private属性。model为复用对象的类型。由于程序并不知道建立何种复用对象,这里通过Bridge将实际创建对象转交objectBridge->create(model);
wrapper* create(string model) { wrapper* ret =NULL; if (objectNumber < maxObjectNumber) { objectNumber++; //建立新的被包装的对象 ret = new wrapper(objectBridge->create(model)); //转交 } return ret; }
(2)复用对象的消亡:void remove(wrapper*);//从对象池中删除,即物理删除。private
void remove(wrapper* o) { objectNumber--; objectBridge->remove(o.object); }
(3)获取的复用对象:在需要一个Reusable对象时,客户端调用AcquireReusable方法。如果池是空的,那么AcquireReusable方法创建一个Reusable对象(如果能够),否则,就等待知道有Reusable对象返回集合。
31.2.4 manager object的管理策略
(1)对象的产生策略
①void setInitPoolSize();//定义对象池初始化时缺省的对象数量
②void createByStrategy();//采用何种策略创建空闲对象
(2)对象的回收策略
①客户通过acquiredReusable获得一个复用对象,然后在使用完后主动归还得复用对象。
②但不能假设客户端使用完对象后,肯定会归还对象,而且有时还有可能客户端程序因为程序异常或死锁使得对象无法归还。设置复用对象最大使用时间:void setMaxUseTime(long time);当超时的时候就强制回收。超过最大额定值时(回收由时间线程定时检查)。
(3)对象的消亡策略
①当复用对象数量超过额定值时,系统归还当前空闲复用对象所占资源以减轻系统 的负担。
②策略:如一次性将空闲对象全部回收或部分回收。
【编程实验】模拟一个数据库连接池进行实现
//新设计模式——对象池模式 //场景:数据库连接池 #include <iostream> #include <string> #include <vector> using namespace std; typedef void Object; //用户需要的实际的东西都要实现这个接口 class IConnection { public: virtual Object* getConnection() = 0; virtual void setConnection(Object* obj) = 0; }; //实现类:用户真正需要的东西,比如数据库连接 class Connection : public IConnection { Object* conn; public: Object* getConnection(){return conn;} void setConnection(Object* obj) { conn = obj; } }; //池子中放的东西(具有状态及用户实际需要的东西) class PoolItem { private: bool m_isUse; IConnection* conn; public: PoolItem(IConnection* conn) { this->conn = conn; m_isUse = false; } bool isUse(){return m_isUse;} void setIsUse(bool value) { m_isUse = value; } IConnection* getConnection() { return conn; } }; //池子管理对象 class PoolManager { private: vector<PoolItem*> items; public: //往池子里放东西(多线程时可考虑同步) void add(IConnection* conn) { items.push_back(new PoolItem(conn)); } //释放对象(多线程时可考虑同步) void release(IConnection* conn) { vector<PoolItem*>::iterator iter = items.begin(); while( iter != items.end()) { PoolItem& item = *(*iter); if(item.getConnection() == conn) { item.setIsUse(false); break; } ++iter; } } //得到池中的对象(多线程时可考虑同步) IConnection* get() { IConnection* ret = NULL; vector<PoolItem*>::iterator iter = items.begin(); while( iter != items.end()) { PoolItem& item = *(*iter); if(! item.isUse()) { item.setIsUse(true); ret = item.getConnection(); break; } ++iter; } return ret; } }; //连接池对象(用户真正需要关心的池子) class ConnectionPool { private: static PoolManager manager; public: //批量添加连接对象 void addConnections(int count) { for(int i=0; i<count; i++) { manager.add(new Connection()); } } //得到连接对象 static IConnection* getConnection() { return manager.get(); } //释放连接 static void release(IConnection* conn) { manager.release(conn); } //清除所有连接 static void clearConnection() { } }; PoolManager ConnectionPool::manager; int main() { return 0; };
31.2.5 小结
(1)该模式通过定义6个接口和两个抽象扩展对象(RealObjectCreator和PoolManager)。通过实现RealObjectCreator抽象对象,可以将整个对象池模式扩展到新的应用领域 。
(2)通过实现PoolMnanger抽象对象,可以针对不同的不对象实现不同的管理策略,来完成复用对象的建立、消亡和管理等诸多工作。