第31章 新的设计模式(2)

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抽象对象,可以针对不同的不对象实现不同的管理策略,来完成复用对象的建立、消亡和管理等诸多工作。

时间: 2024-11-07 04:49:32

第31章 新的设计模式(2)的相关文章

第31章 新的设计模式

31.1 规格模式(Specitification Pattern) 31.1.1 查询筛选条件 (1)场景:根据条件从数据库的用户表中筛选出对象 (2)存在问题 ①findUserByAgeThan和findUserByName两个方法中除了if后面的判断条件不同,其他地方完全一样 ②这两个程序中唯一的变化点就是条件语句,可以将这里封装起来,后面的例子会设计一个规格类,用于封装整个条件语句. [编程实验]根据条件筛选用户表数据 //新设计模式——规格模式 //实例:实现不同条件的查询(不使用规

第31章 项目实战-PC端固定布局6

第31 章项目实战-PC 端固定布局[6]学习要点:1.分离CSS2.头部区域3.内容区域 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.分离CSS本节课,我们将要创建一个新的页面:旅游资讯.那么,现在需要解决的问题是,如果把首页重复的部分移植到新的页面而减少冗余.最恰当的方法就是:将CSS 部分中重复的部分分离出来,单独创建一个CSS,以便后续的页面重复调用.而首页的HTML 重复的部分,一般是通过动态网页,比如PHP 等解决重复问

1124: 零起点学算法31——开始新的起程

1124: 零起点学算法31--开始新的起程 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 2861  Accepted: 1381[Submit][Status][Web Board] Description 很开心大家学到现在. 从今天开始大家要有一个新的起程. 我们开始接触循环了! 你能让计算机计算1+2+3+...+10吗? 你能让计算机计算1+2+3+.._100吗? 只要告诉计算机,你

第31章 项目实战-PC端固定布局8

第31 章项目实战-PC 端固定布局[8]学习要点:1.归类合并2.子导航 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.归类合并在前面几节课中,有一部分HTML 代码比较松散,没有统一到一个类别块里.比如:很多的标签超链接没有归类到UL 里,导致一些问题等.//松散的<a>标签<a href="###">曼谷(12)</a><a href="###">东京

第31章 项目实战-PC端固定布局7

第31 章项目实战-PC 端固定布局[7]学习要点:1.侧栏制作2.详细代码 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.侧栏制作本节课,主要设计一下内容页面的侧栏部分,分三个小块.经过思考,侧栏会包含一些图片,而主要部分也会包含图片,那么侧栏放在左边可能会和主栏的图片冲突导致不协调,所以,我们把侧栏更换到右边.//实际上,还去掉了高度,让其自适应#container {width: 1263px;margin: 30px auto

第31章 项目实战-PC端固定布局3

第31 章项目实战-PC 端固定布局[3]学习要点:1.搜索区2.插入大图3.搜索框 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.搜索区本节课,我们接着header 头部往下,来设计一块搜索区.这个区域,可以是广告大图,也可以是用户注册,也可以是一个搜索条,都是一个大幅背景,内嵌一个表单.具体造型如下:从表面上来分析,就是插入一张背景大图,然后居中一个搜索条.但是,我们要求最小在1280 分辨率.最大在1920 分辨率能保持最佳的观

第31章 项目实战-PC端固定布局5

第31 章项目实战-PC 端固定布局[5]学习要点:1.底部区域2.说明区域3.版权及证件区 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.底部区域本节课,我们将探讨一下首页中最底部的区域.这部分区域由两个部分组成,一个是说明内容,有:合作伙伴.旅游FAQ 和联系方式,还有一个就是版权声明及各种手续证件编号.//底部区域父元素<footer id="footer">...</footer>//底部父元

第31章 项目实战-PC端固定布局4

第31 章项目实战-PC 端固定布局[4]学习要点:1.热门旅游区2.标题介绍区3.旅游项目区 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.热门旅游区本节课,我们将探讨一下首页最核心的部分,旅游区.这块内容由两个部分组成,一个是大标题,表示热门旅游区域.其次就是旅游项目的图片展示区域.具体如下://热门旅游区父元素<div id="tour">...</div>//旅游父元素#tour {width

第31 章项目实战-PC 端固定布局10

第31 章项目实战-PC 端固定布局[10]学习要点:1.机票预定2.代码详解 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.机票预定机票预定页面,具体如下:二.代码详解//全部代码<form action="###"><h2>机票预定</h2><div class="type"><p>航程类型<mark>单程</mark>