设计模式之对象池机制

from abc import ABCMeta, abstractmethod
import logging
import time


"""设计要点:两个核心对象(进行池化的对象、对象池)、三个关键动作对象(借用对象、使用对象、归还对象)
   使用注意事项:对已归还的对象的引用,不能在进行任何其他操作,否则将产生不可预料的结果(使用引用计数技术sys.getrefcount())
   应用场景:适用于那些初始化和销毁的代价高且需要经常被实例化的对象,如大对象、需占用I/O的对象
   实际应用:线程池、连接池等
"""


# 打印INFO以上的信息
logging.basicConfig(level=logging.INFO)


class PooledObject:
    """池对象,池化对象"""
    def __init__(self, obj):
        self.__obj = obj
        self.__busy = obj

    def getObject(self):
        return self.__obj

    def setObject(self, obj):
        self.__obj = obj

    def isBusy(self):
        return self.__busy

    def setBusy(self, busy):
        return self.__busy = busy


class ObjectPool(metaclass=ABCMeta):
    """对象池"""
    """对象池初始化大小"""
    InitialNumOfObjects = 10
    """对象池的大小"""
    MaxNumOfObjects = 50

    def __init__(self):
        self.__pools = []
        for i in range(ObjectPool.InitialNumOfObjects):
            obj = createPoolObject()
            self.__pools.append(obj)

    @abstractmethod
    def createPoolObject(self):
        pass

    def borrowObject(self):
        """借用独享"""
        # 如果找到空闲对象,直接返回
        obj = self.__findFreeObject()
        if obj is not None:
            logging.info("%x对象已被借用,time:%s", id(obj), time.strftime(r"%Y-%m-%d %H:%M:%S", time.localtime(time.time())))
            return obj
        # 如果对象池还未满,则添加新的对象
        if(len(self.__pools) < ObjectPool.MaxNumOfObjects):
            pooledObj = self.addObject()
            if pooledObj is not None:
                pooledObj.setBusy(True)
                logging.info("%x对象已被借用,time:%s", id(obj), time.strftime(r"%Y-%m-%d %H:%M:%S", time.localtime(time.time())))
                return pooledObj.getObject()
        return None

    def returnObject(self, obj):
        """归还对象"""
        for pooledObj in self.__pools:
            if(pooledObj.getObject() == obj):
                pooledObj.setBusy(False)
                logging.info("%x对象已被归还,time:%s", id(obj), time.strftime(r"%Y-%m-%d %H:%M:%S", time.localtime(time.time())))
                break

    def addObj(self):
        """添加新对象"""
        obj = None
        if(len(self.__pools)<ObjectPool.MaxNumOfObjects):
            obj = self.createPoolObject()
            self.__pools.append(obj)
            logging.info("添加新对象%x,time:%s", id(obj), time.strftime(r"%Y-%m-%d %H:%M:%S", time.localtime(time.time())))
            return obj

    def clear(self):
        """清空对象池"""
        self.__pools.clear()

    def __findFreeObject(self):
        """查找闲置对象"""
        obj = None
        for pooledObj in self.__pools:
            if not pooledObj.isBusy():
                obj = pooledObj.getObject()
                pooledObj.setBusy(True)
                break
        return obj

 

posted @ 2020-06-02 00:05  找回失去的自我  阅读(188)  评论(0编辑  收藏  举报