将对象池放入对象类中

问题描述 投票:0回答:1

我正在构建一个对象池,发现定期引用工厂或对象池来处理对象真的很乏味。相反,我正在考虑将池直接构建到对象的类中。

抽象对象类:

class Object(ABC):
    _pool = []
    _max_pool_size = 10
    
    def __new__(cls, *args, **kwargs):
        if cls._pool:
            instance = cls._pool.pop()
            instance.__init__(*args, **kwargs)
            return instance
        else:
            return super().__new__(cls)
    
    @classmethod
    def release(cls, instance):
        if len(cls._pool) < cls._max_pool_size:
            cls._pool.append(instance)
 

实施:

@dataclass
class FooObject(Object):
    n: int

foo_1 = FooObject(1)
FooObject.release(foo_1)

但是在研究对象池设计模式时,分离池、对象并使用工厂似乎更常见。这是为什么?使用这种方法会遇到什么问题?

design-patterns object-pooling
1个回答
0
投票

您可以从不同的角度回答您的问题。

  • 封装:您确实想要封装管理池所需的逻辑。
  • 信息隐藏:您确实希望向其他对象隐藏池逻辑的内部结构,例如
    Object
  • 单一责任:“一个类应该只有一个改变的理由”
  • 解耦:您不想强制对对象的依赖只是为了使用它的一些实际上与暴露对象本身无关的功能。例如,某些类只对池感兴趣,例如检查它包含多少对象。这个类不必知道
    Object
    。我们必须能够访问池而不必处理
    Object
  • 可测试性:我们希望隔离池,以便我们可以独立测试它。
  • 可扩展性:我们希望能够扩展池的功能,例如通过子类化它。
  • 可维护性(尽管遵循前面的原则已经解决了这个问题):我们不希望能够在不接触
    Object
    类的情况下维护池。 Pool 和
    Object
    使用完全独立的逻辑。例如,
    Object
    可以处理用户凭据。为什么这样的对象还包含管理池的逻辑?将这两个职责分开还可以使
    Pool
    Object
    类位于不同的逻辑位置(源文件、DLL 等)或物理位置(例如客户端-服务器)。
  • 可重用性:我们可能希望在不同的上下文或应用程序中重用我们复杂的池,可能使用不同的对象类型。只有当我们将池与其池中的对象分开时,这才有可能。

如果您了解一些 OO 设计原则,您会觉得使用

Object
来实现自己的池在语义上是错误的设计决策。
除非你是一只乌龟,否则房子和里面的居民是两个完全独立的物体,没有任何共享。一个使用另一个。两者必须单独存在。两者都有不同的个体寿命。两者的工作方式和行为方式都不同。

虽然可以通过

Object
本身实现对象池,但它会产生丑陋且过于复杂的代码和类型之间的关系。

如果您能回答以下问题,您也可以回答您自己的问题:

“为什么我们没有一个包含应用程序的大类?”

© www.soinside.com 2019 - 2024. All rights reserved.