假设你有这样的代码:
_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()...
对我而言,这是一个糟糕的模式,有些缺点:
Doer
可以在不满足前提条件的情况下创建Init
。如果它被更改以便可以多次调用,则必须添加额外的逻辑来检查变量是否已经定义,并且必须传递大量NULL值以跳过重新初始化。另一方面,一些专业人士:
Init(5, "user/pass", 2, "user/pass")
就个人而言,我认为缺点超过了专业人士,即可测试性和有保证的前提条件超过了简单性和便利性。
答案 0 :(得分:2)
在我看来,这个例子的唯一问题是使用全局状态。所以不要这样做。
说真的 - 你担心的问题可以通过在Doer出现时将适当的上下文传递给Doer来解决。在某些情况下,“适当的上下文”可能是一些简单的参数(例如读者列表和编写者列表),或者它可能是一个更复杂的聚合对象(“连接管理器”可能有连接添加和删除外部任何引用它的人。)
明确解决您的缺点:
所以这样做并不是特别便宜:
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函数,这显然符合您的要求。)