Фреймворк Django неплохо подходит для создания подключаемых приложений, которые можно вставлять в разные проекты. Причем, говоря "неплохо подходит", я имею в виду, что он дает базовые средства абстрагирования приложения от среды, в которой оно будет работать: включаемые urlconf-файлы, декоратор permalink, сигналы и т.д. От того, пользуется ли программист этими средствами, и как именно, зависит то, насколько приложение будет независимым, и насколько удобно будет его подключать.
Про сигналы у меня есть мысль, которая кажется мне довольно-таки ценной, и, кажется, я ее нигде пока не встречал.
Польза
Суть, в общем, простая. Если вы делаете подключаемое приложение, надо для него заранее напридумывать набор сигналов на все его ключевые точки. То есть:
- приложение аутентификации должно запускать сигналы "user_logged_in", "user_logged_out", "user_created", "password_changed" и т.д.
- приложение-форум должно запускать сигналы "new_topic", "new_reply"
- приложение с тегами должно запускать сигналы "tag_added", "tag_removed", "new_tag"
Имея такие готовые сигналы, проект, который включает в себя приложение, может навешивать на них разную интересную обработку:
- инвалидация всеразличных кешей (дико полезно!)
- рассылка по почте уведомлений о, например, ответах в топик
- логгинг
- пересчет статистики
Производительность
Стоит, правда, остерегаться рассылки сигналов на слишком частые события, потому что сам механизм диспетчера этих сигналов, хоть и сравнительно быстр, но все равно не бесплатен. Сейчас, например, джанговцы думают, что делать с производительностью сигналов, где например сигналы "pre_init" и "post_init" запускаются внутри Джанго на создание каждого объекта моделей, и когда таких объектов тысячи, это уже заметно влияет на скорость. Поэтому приложение-форум наверное не должно иметь сигнал "article_displayed" — слишком частое и незначительное событие.
Оформление
Последнее, что хочется написать — это как этот набор сигналов лучше оформить. Наверное лучше и проще всего держать в корне приложения файл signals.py, в котором в док-стринге будет человеческое описание сигналов и данных, с ними передаваемых, а сами сигналы могут быть просто экземплярами объектов:
'''
new_topic:
...
new_reply:
...
'''
new_topic = object()
new_reply = object()
Комментарии: 9
Однако, сам об этом подумывал несколько раз за последние полгода, но руки - не доходят, а нужности без кеша пока никакой. Но, видать, буду развешивать. :-) Я уже даже обдумывал, где надо - а где нет.
спасибо, будем пробовать :)
Я использую сигналы для того, чтобы делать приложения полностью независимыми друг от друга. Например у меня есть приложения blog и projects, которые ничего не знают друг о друге, но при изменении Entry обновляется Project.
Делается все через signals.py в корне проекта, который сейчас достаточно тривиальный:
Я бы предложил опцию в settings.py или в аналоге для включения сигналов в каждом приложении — это касательно скорости. Нужны тебе сигналы — включаешь опцию. Плагины сами включают когда им нужно.
А вообще, самое плохое в сигналах — они могут порождить undefined behavior когда их использует несколько приложений, не договорившись друг с другом (т.е. очень часто).
Я много работал с сигналами: в Java Eclipse этих сигналов (там они называются Listener) на каждом окне редактора 150 штук висит. Большинство из них тупые, но когда пишешь свой 151й и от того, каким в очереди он встанет, начинает зависеть поведение программы, и ловишь баг не ты, а только твой клиент и, например, только на 64-битной машине или в специфическом окружении.....
Паттерн Provider-Subscriber, сцуко, опасный!
Небольшое замечание: такие вещи принято называть событиями, а не сигналами. Типовые решения на их основе - Observer (или publish/subscribe), доска объявлений. Понятно, что следовать общепринятой терминологии не обязательно, но так посторонним будет проще понимать, о чём речь. Под сигналами же, как правило, имеют ввиду совсем другие вещи. Удивительно, зачем в django так запутывают пользователей?
Займемся буквоедством? :-)
Название паттерна "Observer" — лишь одно из общепринятых, наряду с этой терминологией есть и другие устоявшиеся в своих сообществах варианты. Слово "сигналы", например, используют в известной библиотеке QT. А в Windows то же понятие назвается "сообщением".
Кроме того, Джанго тут вообще ни причем, потому что использует терминологию библиотеки PyDispatcher, на которой это все и реализовано. И я не встречал Джанго-программистов, которых это как-то сильно запутало. Надуманная проблема, то есть :-)
Что-то в этой идее есть от триггеров на базах данных. Сто лет используется и все рады. Мне кажется, что сигналы для этого и были придуманы.
Но тут ведь засада: заранее для всех список сигналов не составишь и надо придумать не этот список, а какое-то соглашение, которого можно было бы придерживаться для того, чтобы совершенно независимые разработчики могли быть точно уверены, надо ли это "ловить".
(если в посте про это было, сорри, читал немного невнимательно).
В моих взаимоотношениях с сигналами две особенности:
В итоге, я игнорировал их месяц, а потом быстро разгрыз с помощью уже упоминавшейся отличной вики-статьи.
Первое для чего они понадобились, были уведомления jabber-ботом об изменениях на сайте. После первого применения сигналов обычно смотришь на архитектуру приложения по-другому.
Спасибо, сигналы :-)
Пардон, что не в тему. Алексей, меня сейчас очень интересует работа с джаббер-ботом. Можешь показать пример использования? Лучше в почту, glader.ru(at)gmail(d)com. Заранее спасибо.