Фреймворк Django неплохо подходит для создания подключаемых приложений, которые можно вставлять в разные проекты. Причем, говоря "неплохо подходит", я имею в виду, что он дает базовые средства абстрагирования приложения от среды, в которой оно будет работать: включаемые urlconf-файлы, декоратор permalink, сигналы и т.д. От того, пользуется ли программист этими средствами, и как именно, зависит то, насколько приложение будет независимым, и насколько удобно будет его подключать.

Про сигналы у меня есть мысль, которая кажется мне довольно-таки ценной, и, кажется, я ее нигде пока не встречал.

Польза

Суть, в общем, простая. Если вы делаете подключаемое приложение, надо для него заранее напридумывать набор сигналов на все его ключевые точки. То есть:

Имея такие готовые сигналы, проект, который включает в себя приложение, может навешивать на них разную интересную обработку:

Производительность

Стоит, правда, остерегаться рассылки сигналов на слишком частые события, потому что сам механизм диспетчера этих сигналов, хоть и сравнительно быстр, но все равно не бесплатен. Сейчас, например, джанговцы думают, что делать с производительностью сигналов, где например сигналы "pre_init" и "post_init" запускаются внутри Джанго на создание каждого объекта моделей, и когда таких объектов тысячи, это уже заметно влияет на скорость. Поэтому приложение-форум наверное не должно иметь сигнал "article_displayed" — слишком частое и незначительное событие.

Оформление

Последнее, что хочется написать — это как этот набор сигналов лучше оформить. Наверное лучше и проще всего держать в корне приложения файл signals.py, в котором в док-стринге будет человеческое описание сигналов и данных, с ними передаваемых, а сами сигналы могут быть просто экземплярами объектов:

'''
new_topic:

    ...

new_reply: 

    ...

'''

new_topic = object()
new_reply = object()

Комментарии: 9

  1. Александр Соловьёв

    Про сигналы у меня есть мысль, которая кажется мне довольно-таки ценной, и, кажется, я ее нигде пока не встречал.

    Однако, сам об этом подумывал несколько раз за последние полгода, но руки - не доходят, а нужности без кеша пока никакой. Но, видать, буду развешивать. :-) Я уже даже обдумывал, где надо - а где нет.

  2. bsn

    спасибо, будем пробовать :)

  3. Дима Догадайло

    Я использую сигналы для того, чтобы делать приложения полностью независимыми друг от друга. Например у меня есть приложения blog и projects, которые ничего не знают друг о друге, но при изменении Entry обновляется Project.

    Делается все через signals.py в корне проекта, который сейчас достаточно тривиальный:

    from concept.projects.models import Project
    from concept.blog.models import Entry
    
    def touch_projects(instance):
        """Update last modified date of all projects connected to the changed blog entry."""
        for p in Project.objects.filter(slug__in = instance.tags.split(',')):
            p.save()                        # update Project.last_modified
    
    dispatcher.connect(touch_projects, signal=post_save, sender=Entry)
    
  4. Yuri Baburov

    Я бы предложил опцию в settings.py или в аналоге для включения сигналов в каждом приложении — это касательно скорости. Нужны тебе сигналы — включаешь опцию. Плагины сами включают когда им нужно.
    А вообще, самое плохое в сигналах — они могут порождить undefined behavior когда их использует несколько приложений, не договорившись друг с другом (т.е. очень часто).
    Я много работал с сигналами: в Java Eclipse этих сигналов (там они называются Listener) на каждом окне редактора 150 штук висит. Большинство из них тупые, но когда пишешь свой 151й и от того, каким в очереди он встанет, начинает зависеть поведение программы, и ловишь баг не ты, а только твой клиент и, например, только на 64-битной машине или в специфическом окружении.....
    Паттерн Provider-Subscriber, сцуко, опасный!

  5. ods

    Небольшое замечание: такие вещи принято называть событиями, а не сигналами. Типовые решения на их основе - Observer (или publish/subscribe), доска объявлений. Понятно, что следовать общепринятой терминологии не обязательно, но так посторонним будет проще понимать, о чём речь. Под сигналами же, как правило, имеют ввиду совсем другие вещи. Удивительно, зачем в django так запутывают пользователей?

  6. Иван Сагалаев

    Займемся буквоедством? :-)

    Название паттерна "Observer" — лишь одно из общепринятых, наряду с этой терминологией есть и другие устоявшиеся в своих сообществах варианты. Слово "сигналы", например, используют в известной библиотеке QT. А в Windows то же понятие назвается "сообщением".

    Кроме того, Джанго тут вообще ни причем, потому что использует терминологию библиотеки PyDispatcher, на которой это все и реализовано. И я не встречал Джанго-программистов, которых это как-то сильно запутало. Надуманная проблема, то есть :-)

  7. Greg

    Что-то в этой идее есть от триггеров на базах данных. Сто лет используется и все рады. Мне кажется, что сигналы для этого и были придуманы.

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

    (если в посте про это было, сорри, читал немного невнимательно).

  8. Алексей Гусев

    В моих взаимоотношениях с сигналами две особенности:

    1. Если бы они назывались событиями, я бы быстрее обратил на них внимание и изучил.
    2. Если бы они назывались событиями, я бы как обычно подумал, что это что-то из области бесконечных циклов, и не стал бы так их грызть :-)

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

    Спасибо, сигналы :-)

  9. Glader

    Пардон, что не в тему. Алексей, меня сейчас очень интересует работа с джаббер-ботом. Можешь показать пример использования? Лучше в почту, glader.ru(at)gmail(d)com. Заранее спасибо.

Добавить комментарий