Мне кажется, что единственной проблемой в этом примере является использование глобального состояния.Так что не делайте этого.
Серьезно - проблемы, о которых вы беспокоитесь, решаются путем передачи соответствующего контекста Делателю, когда он появляется.В некоторых случаях «соответствующий контекст» может представлять собой пару простых аргументов (например, список читателей и список авторов) или это может быть более сложный агрегатный объект («менеджер соединений», в который могут добавляться и удаляться внешние соединения).любому, кто ссылается на него).
Чтобы явно указать ваши минусы:
- , если у Doer есть предварительные условия, проверьте их.Если они не выполнены, выведите исключение.
- (Решено, если ConnPool передается в качестве параметра в ctor или рабочую функцию.)
- Сделайте, чтобы Init создал вещь, которую вы передадите 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, что, очевидно, будет соответствовать вашим требованиям.)