MyTetra Share
Делитесь знаниями!
О, смотри-ка какое хорошее место. Дайте два!
Seaside: веб-фреймворк на основе continuations
12.02.2010
13:48
Раздел: Компьютер - Программирование - Язык PHP

Довольно длинное введение

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

Написание сложных (и не очень) веб-приложений обычно наталкивается на кучу проблем, и основная — это то, что протокол HTTP не подразумевает никакого состояния — и поэтому это состояние приходится за собой таскать в виде cookies, скрытых полей в формах и букета параметров методов GET/POST. Плюс к этому, линейные переходы между страницами — по сути, аналог оператора goto — приводят к тому что дизайн многих веб приложений представляет из себя мешанину из процедурного и как-бы-объектно-ориентированного кода, сумбурных обращений к базе данных, разбавленных HTML разметкой.

Проблемы эти стараются решить современные фреймворки для веб-разработки, прежде всего Django, CakePHP и Ruby on Rails, в которых авторы постарались максимально отделить представление от логики, упростить работу с базой данных засчет всяких ORM подсистем и вообще структурировать приложение (в той или иной степени) заставляя его следовать классическому, но подзабытому в 90-е паттерну Model-View-Controller. В Ruby on Rails, скажем, под моделью понимаются данные, хранящиеся в БД, view — это система шаблонов, на основе которых генерируются страницы и контроллер — это собственно бизнес-логика.

Однако же проблема таскать за собой "состояние" сессии остается, хотя и для ее решения фреймворки предлагают много всяких вспомогательных средств.

Па-пам

Старики помнят, что термин "объектно-ориентированный" был изобретен для того чтобы назвать так язык Smalltalk. В дискуссиях о том, насколько тот или иной язык ОО обычно гуру ссылаются именно на него, как на эталон тру ОО языка.

Более того, паттерн MVC у тех же стариков ассоциируется прежде всего с GUI библиотеками Smalltalk, именно там этот паттерн родился и получил широкое применение (потом эта вся идеология перекочевала в ОС NextStep, а из нее в Mac OS(X), если кто не в курсе).

Возвращаясь к веб-разработке, многие наверное читали эссе Пола Грэма Beating the Averages, как Пол с товарищами написали на лиспе систему для создания веб-магазинов и потом продали ее за много миллионов баксов Yahoo!. Там они, кроме всего прочего, использовали continuations как механизм передачи управления между страницами. Continuation'ы хранились на сервере в словаре, а ссылки на страницах содержали как параметр id того continuation, который надо выполнить для генерации страницы.

Если сложить вместе концепцию continuations, MVC в качестве основного паттерна для архитектуры всего приложения и smalltalk в качестве языка разработки — получим Seaside, фреймворк для разработки сложных веб-приложений, не думая о большинстве вышеописанных проблем.

Немножко подробнее про continuations в вебе

С логикой и control flow в вебе проблем несколько — во первых, вышеупомянутое состояние сессии: таскать его между страницами через параметры POST/GET довольно неудобно да и иногда просто нереально, а наличие у юзера кнопок "назад" и "открыть в новом окне" создает проблемы, если мы храним состояние в куках или сразу сохраняем в базе данных введенные в формы данные.

Но отличное решение этой проблемы уже давно существует и реализовано во многих динамических языках, начиная с лиспа. Называется continuation — тут я описывал подробнее, что это, но если в двух словах — мы можем поставить выполнение программы в каком-то месте "на паузу", и потом с объектом "поставленная на паузу программа" обращаться как с любым другим — продолжить выполнение с того места (сколько угодно раз, заново), сохранить, передать, удалить за ненадобностью.

Например, представим себе такой пример: пользователь заполняет форму, нажимает ОК, но одно поле заполнено неверно, и мы хотим показать ему страничку с предупреждением и кнопкой ОК, и вернуться обратно к той (уже частично заполненной им) форме.

В стандартном случае мы передаем скрипту, выводящему страницу с предупреждением значения заполненных полей, а он потом передает их обратно. Как-то так:

/show_form.php

-> validate_form.php?userName=John&phone=02

-> show_warning.php?userName=John&phone=02

-> show_form.php?userName=John&phone=02

В фреймворках, основанных на continuations метод showForm() просто вызывает validateForm(), которая вызывает showWarning(), и на время, когда юзеру надо показать отрендеренную страницу все состояние сохраняется в continuation. Потом, когда юзер жмет OK — все возобновляется с того места где приложение остановилось.

По сравнению с традиционным подходом тут целых несколько преимуществ: во-первых, мы не заботимся о том, как таскать состояние через страницы; во-вторых, структура программы становится понятнее, это своего рода переход от GOTO к процедурам; в-третьих, поскольку состояние теперь не наша забота, куски кода становятся более модульными, функции showWarning() уже не надо знать ничего ни о каких формах.

Последнее особенно хорошо иллюстрируется примером из дистрибутива Seaside: пять компонентов (счетчиков) на одной странице, состояние обо всех некоторым образом передается между страницами, но каждый счетчик ничего не знает о других — вся логика и представление сосредоточено внутри класса, отвечающего за компонент, а не размазана по скрипту сгенерить_страницу_с_пятью_счетчиками.php. Это именно благодаря тому, что состояние сохраняется и передается автоматически между вызовами. И кнопка back в браузере отлично работает без всяких усилий со стороны разработчика.

Seaside

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

Немаловажный момент — Seaside принципиально не использует никакой системы шаблонов, подобно Ruby on Rails и Django — XHTML код генерится с помощью набора специальных классов, благодаря чему генерацию XHTML можно разносить по методам, применять к ним инструменты для рефакторинга Smalltalk-овского кода (а среда тут предоставляет их очень богатый набор). Конечно, дизайнерам править XHTML будет немного сложнее, но, по-хорошему, им и не надо: XHTML призван отвечать за "семантику" страницы, а для представления ее существует CSS.

Вообще среда разработки в Smalltalk (точнее Squeak, основная но не единственная реализация Smalltalk, в которой работает Seaside) заслуживает отдельного большого поста — настолько это инопланетное создание. Чего стоит только тот факт что там нету понятия исходных файлов — есть только один большой рантайм, все классы и методы правятся "на лету", не останавливая работы приложения. Система контроля версий тоже своя, и diff работающий не на уровне текста, а на уровне классов и методов. Поначалу больше всего расстраивает то, что в Squeak нельзя воспользоваться своим любимым редактором, но мало какой редактор предоставляет столько инструментов для рефакторинга и автоматической генерации кода, как System Browser в Squeak.

Кроме всего этого, к Squeak/Seaside прилагаются очень неплохие инструменты для отладки, тестирования и настройки производительности. В отладочном режиме вообще много приятностей — когда в приложении происходит какой-то эксепшен, можно нажать кнопку Debug и начать отлаживать с этого места в Squeak. Для десктопных средств разработки в этом ничего выдающегося нету, но для веб — это большой шаг вперед.

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

Лучше, конечно один раз увидеть: скринкаст здесь — рефакторинг приложения (не веб-) в squeak, не останавливая его работы; и тут — создание блога за 15 минут в Seaside. Заметьте, как товарищ ловко фиксит там баг на лету, опять же без остановки приложения.

Кто-то же должен за это платить?

Естественно, все это оборачивается несколько более высокими аппаратными требованиями. Seaside изначально ставит стоимость времени программиста много выше стоимости железок. Squeak кушает изрядно памяти и процессорного времени (хотя по скорости выполнения, говорят, как минимум не медленнее питона и руби). По стабильности рантайма проблем нету, если кого-то беспокоит что это все может быть несколько "сыровато" — виртуальная машина squeak разрабатывается уже лет 10 как, причем довольно серьезными и профессиональными дядьками, начиная с того же Алана Кея.

Ну и..

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

Ссылки. Много ссылок

Блог "On Smalltalk" много про squeak, smalltalk и seaside

Блог "HREF Considered Harmful" про про seaside и внутренности squeak

Подробно о continuations в вебе Статья "Seaside - a Multiple Control Flow Web Application Framework" [PDF]

Сравнение Rails Vs Seaside (+ в комментах интересная битва между любителями Rails и автором)

Другое интересное сравнение Rails и Seaside от опытного программиста на java Дэвида Поллака. Судя по всему, Дэвида все-таки не устроило ни то, ни другое, поэтому сейчас он активно разрабатывает фреймворк на базе Scala, это отдельная интересная тема :)

Сайт Seaside

Сайт Squeak

Бесплатный хостинг для некоммерческих Seaside приложений

Туториалы к Seaside: вот и вот, и еще несколько в гугле можно найти. К сожалению, кое-какие из них местами устарели.

Так же в этом разделе:
← Содержание ...
 
MyTetra Share v.0.35
Яндекс индекс цитирования