Макс Ищенко решил не следовать моему совету выбрать Django для веб-разработки и выбрал TurboGears :-). Ни в коем случае не хочу как-то спорить с этим решением: может быть миллион причин выбрать то или это. Вместо этого я, как пропагандист Django, хочу прокомментировать то, как он обосновал свое решение в двух следующих постах.

Вот цитата:

... разработчик(и) TurboGears не стали изобретать велосипед, а взяли готовые, зарекомендовавшие себя компоненты: MochiKit, Kid, CherryPy, SQLObject. Это дает не только внушительный объем функциональности, но и доступ к сложившимся вокруг этих проектов коммьюнити.

Классический случай изобретения велосипеда — это когда некий программист, смотря на какую-то библиотеку, говорит себе: "и зачем такие сложности?" и начинает лепить что-то свое, безусловно "правильное" и "эффективное". Потом оказывается, что в задаче, которую он решает, гораздо больше сложностей и неочевидностей, чем было видно в начале. И выходит, что вся та сложность в написанных решениях есть не просто так, а соответствует реальности. В итоге получается, что новое решение получается таким же кривым и волосатым, но зато у него не хватает половины функциональности, и оно глючит. Думаю, все мы когда-то такое делали :-)

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

И Django, и TurboGears решают одну и ту же задачу: создание полного набора технологий ("full stack") для разработки веб-сайта: доступ к БД, контроллер веб-запросов, шаблоны. Только в Django все эти компоненты написаны самостоятельно, а TurboGears использует готовые: SQLObject, CherryPy и Kid соответственно. Так вот, в случае с Django я считаю, что написание с нуля было оправдано.

Переизобретение

Сразу сознаюсь, что с компонентами TurboGears я не знаком очень близко, поэтому могу и глупость какую сморозить :-). Но два из них: CherryPy и Kid — я когда-то смотрел, и они мне не понравились. Их действительно стоило переизобрести :-)

В CherryPy резко не понравилось то, что он сам жестко задает структуру URL. То есть да, он конечно полезен тем, что избавляет от написания логики вызова нужного кода по полученному веб-запросу, но как будет выглядеть URL он определяет сам. И сразу скажу, что определяет совсем не так, как мне бы понравилось: все параметры передаются через GET (или POST, видимо). В итоге URL'ы выглядят так:

http://server/?func=SomeFunc&id=3

Некрасиво :-(

Обработка же URL в Django — это сказка. Все построено на файле ("urlconf" на местном жаргоне), в котором соответствие URL'ов обрабатывающим функциям задается регулярками, и теми же регулярками вы можете выбрать из URL'ов значимые части и передать в качестве параметров в обрабатывающую функцию. Вид URL'ов можно задать какой угодно:

http://server/SomeFunc/3/
http://server/SomeFunc-3
http://server/subdomain-(3)/SomeFunc/

Плюс эти структуры URL'ов можно подключать друг к другу, и ваше приложение, включенное куда-то в структуру URL другого проекта, даже не заметит этого, потмоу что будет получать только известную ему часть URL. Добавьте к этому, что функция-обработчик получает еще и объект request, в котором удобно и единообразно собрана вся среда запроса: кукесы, GET, POST, сессия, авторизованный юзер и т.п...

Шаблоны Kid и вовсе страдают ограниченным применением: ими можно генерировать только well-formed XML, и именно гарантия well-formed'ности и является их основной фишкой. Проблема только в том, что шаблонами иногда нужно генерировать не только XML :-). А например CSS или просто текст или какой-нибудь код. Мало ли примененений бывает... Ну и кроме того, на мой вкус, впихивание шаблонной логики в параметры тегов просто плохо выглядит, и это тяжело править.

У шаблонной системы Django есть другая фишка: в ней намерено сильно ограничена логика для того, чтобы в шаблоны не утекала бизнес-логика приложения. Это утекание, к сожалению, часто становится проблемой многих шаблонных систем, которые позволяют фактически выполнять внутри себя питоновский код, что ведет к тому, что со временем уже никто сходу не знает, где начинать искать ошибку: на уровне контроллера или представления. В Django же написать в шаблоне какую-то нетривиальную логику сложнее вывода элементов списка в <li> просто нельзя.

Есть у TurboGears еще один компонент, которого пока нет в Django — Javascript'овая библиотека MochiKit. И вот тут как раз разработчики Django не стали изобртать ничего нового, а собираются интегрировать к себе тоже известную библиотечку — Dojo. Это показывает, что они не подвержены догмам ("все надо писать самому"), а выбирают решение, исходя из ситуации. (Тем, кто сейчас хочет в комментариях ткнуть меня носом вот сюда: то был юмор :-) .)

Интеграция

Еще одна сильная сторона Django по сравнению с TurboGears — интеграция всех компонентов. Они пишутся вместе, одной и той же командой, и поэтому хорошо работают вместе. Не могу сейчас конкретно ткнуть пальцем в пример, показывающий различия, но это может проявляться даже в таких мелочах, что переменная авторизованного юзера в запросе и шаблоне называется одинаково, или что все кодирование спецсимволов для URL'ов (%XX) делается только в каком-то одном месте, а не по всему фреймворку. И, например, документация для Django находится в одном месте и написана в одном стиле.

Другими словами, работать с умно интегрированной системой обычно гораздо приятней. А с тем, чтобы не допускать излишне тесной связанности компонентов, разработчики успешно справляются.


Короче говоря, даешь новые велосипеды! С углепластиковой рамой и GPS'ом под задницей :-)

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

  1. Андрей Хаврюченко

    Как человек, который работает с Максом над реальным проектом, могу сказать, что мы, для проекта с запланированной катастрофической близостью дедлайна, взяли всё-таки Django :)

  2. Alena

    Я помню, что в Django были проблемы с нелатинскими символами, в частности с русскими. Ты даже патчи делал по этому поводу. Все проблемы разрешены? Как с этим обстоит дело в TurboGears?

  3. bogus

    К сожалению, не довелось работать ни с тем ни с другим.
    Однако, urlconf - это не переизобретение ли mod_rewrite?

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

    Да, переизобретение mod_rewrite. И опять хорошее :-).

    Начать с того, что я сам, и большинство программистов, которых я знаю, не в состоянии составить rewrite'ы как надо с первого раза. Синтаксис слишком странен и витиеват, и заставить их работать часто получается только тупым перебором похожих вариантов.

    Следующая проблема: mod_rewrite — это Апачевская вещь, а Django работает не только на нем.

    Наконец, urlconf дает просто более красивые функции. Вот например такая регулярка:

    (r'items/(\\d+)/(\\w+)/$', 'item_handler', None)
    

    ... и соответствующий обработчик:

    def item_handler(request, id, action):
      ...
    

    Обработчик получит части URL'а, взятые в скобки, сразу в свои параметры (id и action). В коде это выглядит красивее, чем request.GET['id'] и request.GET['action'].

    P.S. Кстати, в версии 2.0 Wordpress тоже отказался от mod_rewrite в сторону внутреннего разбора.

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

    Насчет нелатинских символов. Это, по-моему, хроническая болезнь всех ascii-говорящих разработчиков :-). Тут у Django все довольно неплохо, потому что везде используется по умолчанию utf-8, но не идеально.

    Я писал патч для того, чтобы работала проверка количества символов в текстовых полях форм, и патч этот успешно включили. А вот следующий, исправляющий некоторые фильтры в шаблонах, еще не включили. Лежит здесь: http://code.djangoproject.com/ticket/924, рекомендую всем utf-8-говорящим его использовать :-).

  6. Max Ischenko

    Иван, спасибо за статью. Я думаю написать цикл статей о TurboGears для developers.org.ua и думаю там будет ответы на часть из вопросов затронутых в этом посте.

    Что касается собственно вопроса, тут наверное многое определяется вкусом разработчика. Мне просто нравится TurboGears и поэтому я могу привести кучу доводов в его пользу. Насчет RESTful URLs — вовсе не обязательно иметь урлы вида http://server/?func=SomeFunc&id=3, честно. А вот URLconf мне не понравился. ;-)

  7. DenD

    Начать с того, что я сам, и большинство программистов, которых я знаю, не в состоянии составить rewrite’ы как надо с первого раза.

    Ой, что я слышу. Это была сейчас наглая ложь, или что еще хуже, если это действительно так. Более удобного и простого до гениальности механизма чем mod_rewrite сложно мне представить. Это велосипед, даже более, это - самокат.

    Синтаксис слишком странен и витиеват, и заставить их работать часто получается только тупым перебором похожих вариантов.

    И опять не соглашусь :) Хотелось бы на примерах увидеть.
    Помнится, как только я начинал работать (а перед этим, расписывая свои умения и навыки в резюме, упоминал уверенное владение регулярными выражениями) mod_rewrite вводил меня в состояние паники. Да и с регулярными выражениями я оказался лишь поверхностно знаком. Выручала меня тогда какая-то графическая тулза для KDE, kregexpbuilder или что-то в этом роде (точно не припомню). Недолго, правда, выручала. Очень скоро она стала не нужна. Как оказалось писать правила для mod_rewrite очень просто. А для понимания достаточно редактора с подсветкой скобок.

    Кстати, в версии 2.0 Wordpress тоже отказался от mod_rewrite в сторону внутреннего разбора.

    Ооочень плохой пример для подражания. Не дай бог кому учится web-программированию на сырцах вордпресса.

  8. Max Ischenko

    Ооочень плохой пример для подражания. Не дай бог кому учится web-программированию на сырцах вордпресса.

    Да ладно. Насколько я понимаю, код попадет в top 5% для PHP кода. ;-) Хотя я и не пхп программист.

  9. Игорь Александрович

    На днях наваял патчик для отсылки почтовых сообщений с кодировкой utf-8 (берётся из DEFAULT_CHARSET) вместо us-ascii, если кому интересно.

    http://code.djangoproject.com/ticket/1235

  10. Julik

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

    В условии наличия удобного фреймворка mod_rewrite становится просто еще одним уровнем абстракции (причем неудобным). Django берет это на себя, Rails тоже от этого избавились.

    По-хорошему если бы разработчики Апача наконец-то взялись за ум и разрешили постить на страницы 404 про mod_rewrite в 60 процентах ситуации никто бы и не вспоминал. Но им уперлось.

    В lighttpd он уже не нужен.

  11. Alex Efros

    По поводу изобретения колёс/велосипедов встретилась хорошая фразочка (http://blogs.msdn.com/mikechampion/archive/2006/12/21/the-json-vs-xml-debate-begins-in-earnest.aspx):

    The good thing about reinventing the wheel is that you can get a round one.

    :)

  12. ph

    что мне нравится в django - не принуждает использовать встроенную orm.
    в нем можно свободно использовать SQLObject или sqlalchemy.
    тоже самое с шаблонами и всем остальным.
    и это всё предусмотренно дизайном и не выглядит как грязный хак.

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