gpt4 book ai didi

design-patterns - 是什么让静态初始化函数好、坏或其他?

转载 作者:行者123 更新时间:2023-11-28 20:34:16 24 4
gpt4 key购买 nike

假设您有这样的代码:

_READERS = None
_WRITERS = None

def Init(num_readers, reader_params, num_writers, writer_params, ...args...):
...logic...
_READERS = new ReaderPool(num_readers, reader_params)
_WRITERS = new WriterPool(num_writers, writer_params)
...more logic...

class Doer:
def __init__(...args...):
...
def Read(self, ...args...):
c = _READERS.get()
try:
...work with conn
finally:
_READERS.put(c)
def Writer(...):
...similar to Read()...

对我来说,这是一个不好的模式,有一些缺点:

  1. Doer可以在不满足其先决条件的情况下创建
  2. 代码不易测试,因为无法直接模拟 ConnPool。
  3. Init 必须在第一时间正确调用。如果它发生更改以便可以多次调用,则必须添加额外的逻辑来检查变量是否已定义,并且必须传递大量 NULL 值以跳过重新初始化。
  4. 在线程的情况下,上面加锁变得更复杂
  5. 全局变量没有被用来传达状态(严格来说这不是坏事,而是代码的味道)

另一方面,一些专业人士:

  1. 很方便调用Init(5, "user/pass", 2, "user/pass")
  2. 简单且“干净”

我个人认为利大于弊,即可测试性和有保证的先决条件胜过简单性和便利性。

最佳答案

在我看来,这个例子的唯一问题是全局状态的使用。所以不要那样做。

说真的 - 您担心的问题会在它出现时通过将适当的上下文传递给 Doer 来解决。在某些情况下,“适当的上下文”可能是几个简单的参数(例如,一个读者列表和一个作者列表)或者它可能是一个更复杂的聚合对象(“连接管理器”可能在外部添加和删除连接给任何引用它的人)。

要明确解决您的缺点:

  1. 如果 Doer 有先决条件,验证它们。如果不满足,则引发异常。
  2. (如果将 ConnPool 作为参数传递给 ctor 或 worker 函数,则已解决。)
  3. 让 Init 创建您将传递给 Doer 的东西,而不是创建全局数据。 mock 一下,把要建的类也传过去?基本上,使用某种工厂。
  4. 如果它是共享的,你只需要担心你的状态中的线程安全。如果每个线程都有自己的连接管理器(例如),那么就没有什么可以锁定在这个级别。
  5. (如果您不使用全局变量,自然会解决。)

所以-这样做并不是特别不方便:

class ConnPool:
def __init__(self, numReaders, readerParams, numWriters, writerParams):
(your InitFunction with a bunch of self. prepending)

class Doer:
def __init__(self, connPool, ...):
if not preconditions:
raise DoerPreconditionsNotMetError()
self.connections = connPool

def Read(self):
readers, writers = self.connections._READERS, self.connections._WRITERS
...

所以,我不知道。我不认为这比您的示例特别不简洁或可读性差。 (或者,您可以将连接管理器传递给 Read 函数,这显然可以满足您的要求。)

关于design-patterns - 是什么让静态初始化函数好、坏或其他?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2589540/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com