Вопрос

У меня есть два занятия:Учетная запись и Оператор.Учетная запись содержит список Операторов.Теперь, всякий раз, когда оператор (в списке) получает сообщение, я хочу уведомить объект Account, чтобы он также выполнил некоторую бизнес-логику.

Я думаю о трех альтернативах того, как этого добиться:

1) Храните ссылку внутри Operator на объект container [Account] и вызывайте методы напрямую.Не совсем хорошо из-за циклических ссылок.

2) Используйте события.Насколько я знаю, в Python нет встроенного механизма обработки событий.Итак, этот вариант немного сложен в реализации.

3) Не отправляйте сообщения Операторам напрямую.Вместо этого управляйте только учетными записями и внутри них, внутренне, операторами-обработчиками.Это немного ограничивает, потому что в этом случае я не могу передавать ссылки на операторы.

Интересно, какой подход наиболее выгоден с архитектурной точки зрения.Как вы обычно справляетесь с этой задачей?

Было бы здорово, если бы вы могли указать фрагменты текста на Python.

Это было полезно?

Решение

Ты переоцениваешь это.Серьезно.Python - это не C ++;ваши проблемы не являются проблемами в Python.Просто напишите, что имеет смысл в вашей проблемной области.

"Не совсем хорошо из-за циклических ссылок".

Почему бы и нет?Округлость здесь вообще не имеет значения.Двунаправленные отношения - это великая вещь.Используй их.Python garbage собирает их просто отлично, без каких-либо размышлений с вашей стороны.

Какие возможные проблемы у вас возникают во взаимных (двунаправленных) отношениях?

"... управлять только учетными записями, а внутри них, внутренне, операторами-обработчиками.Это немного ограничивает, потому что в этом случае я не могу передавать ссылки на операторы."

Что?Ваши операторы - это объекты Python, передавайте все, что вы хотите.Все объекты Python являются (по сути) ссылками, не переживайте.

Какие возможные проблемы у вас возникают при манипулировании объектами Operator?

Другие советы

Не существует "универсального" решения для шаблона Observer.Но обычно лучше определить объект EventManager, где заинтересованные стороны могут регистрироваться для определенных событий и публиковать эти события всякий раз, когда они происходят.Это просто создает меньше зависимостей.

Обратите внимание, что вам необходимо использовать глобальный экземпляр EventManager, что может быть проблематично во время тестирования или с общей точки зрения OO (это глобальная переменная).Я настоятельно не советую постоянно передавать EventManager, потому что это загромождает ваш код.

В моем собственном коде "ключом" для регистрации событий является класс события.EventManager использует словарь (класс события -> список наблюдателей), чтобы знать, какое событие куда направляется.Затем в коде уведомления вы можете использовать dict.get(event.__class__, ()) чтобы найти своих слушателей.

Я бы использовал для этого обработку событий.Вам не нужно реализовывать это самостоятельно - я использую pydispatcher - пидиспатчер именно для такого рода обработки событий, и это всегда работало очень хорошо (внутри оно использует слабые ссылки, чтобы избежать проблемы циклических ссылок).

Кроме того, если вы используете фреймворк с графическим интерфейсом, возможно, у вас уже есть фреймворк событий, к которому вы можете подключиться, например PyQt имеет сигналы и слоты.

>>> class Account(object):
...     def notify(self):
...         print "Account notified"
...
>>> class Operator(object):
...     def __init__(self, notifier):
...         self.notifier = notifier
...
>>> A = Account()
>>> O = Operator(A.notify)
>>> O.notifier()
Account notified
>>> import gc
>>> gc.garbage
[]
>>> del A
>>> del O
>>> gc.garbage
[]

Одна вещь, которую вы, возможно, не знаете о методах экземпляра, заключается в том, что они привязываются при поиске при использовании синтаксиса dot.Другими словами, говоря A.notify автоматически привязывает параметр self для notify к A.Затем вы можете сохранить ссылку на эту функцию, не создавая ненужного мусора.

Наконец, вы всегда можете использовать Камаэлия для такого рода вещей.

Фрагменты шаблонов Observer есть по всему Интернету.Хорошим источником надежного кода является активное состояние, например :

http://code.activestate.com/recipes/131499/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top