2008-01-11

Введение в Zope.txt

  2008-01-11 19:01

Введение в Zope3: Введение : Основная цель этой статьи - дать краткий путеводитель по той непознанной новичками области, которая называется Zope3. - Существует Zope Configuration Markup Language (ZCML), с помощью которого в первый момент старта Zope происходит его "сборка" из множества составных частей. Python - современный объектно-ориентированный язык, качество которого вызывает много споров, на которых не стоит осанавливать внимание. Zope использует в качестве хранилища объектов ZODB - объектно-ориентированную базу данных. Существует несколько реализаций ZODB, в том числе доступ к ZODB через ZEO, что позволяет масштабировать Zope или просто выбрать более удобную с вашей точки зрения реализацию. Zope3 использует в основу взаимодействия между объектами кладет компонентную модель: Иными словами, в норме, взаимодействия между составными частями Zope3 осуществляется только тогда и тольк ...

Введение в Zope3:

Введение :

Основная цель этой статьи - дать краткий путеводитель по той непознанной новичками области, которая называется Zope3. Хотя данные в ней определения являются сокращенными и не всегда точными, они помогают оценить тот объем работы, который был вложен в Zope3 разработчиками и тот объем усилий, который нужен для того, чтобы этот объём изучить. Тем не менее, для некоторых продвинутых разработчиков эта статья может стать исчерпывающим описанием, а все необходимое остальное они найдут в исходных кодах или онлайновом справочнике Zope3.

Что такое Zope:

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

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

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

Zope3 состоит из нескольких независимых компонент, каждая из которых играет свою роль:

  • Существует сервер, принимающий запрос из сети и представляющий его в виде компоненты-запроса.
  • Существует брокер запросов, который находит подходящий компонент, активирует его и собирает среду для взаимодействия с запросом.
  • Cуществует иерархия компонент, с которой взаимодействует брокер запросов.
  • Существует абстрактный способ взаимодействия компонент, называемый компонентной моделью. Взаимодействие компонент обычно является частью обслуживания запроса.
  • Существует хранилище, в котором сохраняют состояние объекты, из которых построены компоненты.
  • Существует несколько специализированных служб (реестров), позволяющих локализовать и подбирать компоненты.
  • Существует Zope Configuration Markup Language (ZCML), с помощью которого в первый момент старта Zope происходит его "сборка" из множества составных частей.

Обратите внимание, здесь практически не говорится об объектах - только о компонентах.

Zope3 ориентирован на обслуживание запросов (преимущественно http-запросов, хотя возможны варианты). Главное, что есть некоторая специальная подсистема, которую в науке принято называть "брокер запросов", (правда, в народе она почему-то называется "диспетчер"). Брокер запросов в реализации Zope3 позволяет локализовать подходящий объект по запросу и выполнить запрос, используя его.

Zope3 в качестве языка написания приложений использует Python. Разумеется, возможны альтернативы, но, тем не менее, стандартное API требует python. Python - современный объектно-ориентированный язык, качество которого вызывает много споров, на которых не стоит осанавливать внимание.

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

Хранилище компонент:

Как было сказано выше, хранилище компонент - это совокупность программных средств, обеспечивающих сохранение внутреннего состояния объектов, из которых созданы компоненты. Zope использует в качестве хранилища объектов ZODB - объектно-ориентированную базу данных. ZODB не является базой данных в обычном смысле (т.е. быстрый поиск, индексы и т.п.), ее назначение другое: обеспечить прозрачное сохранение объектов, гарантируя целостность связей между ними. Фактически, работая с ZODB, не нужно задумываться о сохранении объектов: обычная работа с объектами автоматически отражается в ZODB.

Скорость работы ZODB - отдельная большая тема, какие-то размышления на которую можно посмотртеть здесь Speed-Zope3vsMySql.txt, но главное что нужно помнить: ZODB оптимизирована на чтение и ее скорость не имеет большого значения (в рамках разумного, конечно). В подавляющем большинстве случаев ООП, критическими по использованию ресурсов являются другие компоненты.

Существует несколько реализаций ZODB, в том числе доступ к ZODB через ZEO, что позволяет масштабировать Zope или просто выбрать более удобную с вашей точки зрения реализацию.

Взаимодействие между объектами:

Взаимодействие между объектами это важный момент, потому что именно взаимодействие составных частей и основа их взаимодействия объясняет поведение системы в целом.

Zope3 использует в основу взаимодействия между объектами кладет компонентную модель: Иными словами, в норме, взаимодействия между составными частями Zope3 осуществляется только тогда и только в той мере, в которой эти части являются компонентами. Исключения есть - но это скорее чъя-то ошибка или извращение, а не рекомендуемый способ программирования. Компоненты хранятся как разрозненная куча (хотя большинство из них в обычной объектной манере уложены в аккуратную иерархию). Для того чтобы осуществить взаимодействие, надо найти подходящий компонент и применить его. Словом "подходящий" определена достаточно сложная концепция того, что компонент обладает неким "прагматическии смыслом", и в рамках этого "смысла" должна быть возможность использования объекта для данной цели. Со смыслами Zope работать не умеет, вместо этого он работает с их обозначениями, которые называются "интерфейс".

Дадим краткое формальное определение компонентной модели:

Объект
Некоторая сущность, обладающая состоянием и поведением;
Интерфейс
Декларация предпочтительного способа использования объекта (то, что мы назвали "прагматическим смыслом");
Схема (Схема Интерфейса)
Декларация атрибутов и методов, предоставляемых интерфейсом;
Компонент
Некоторая сущность, предоставляющая предопределенный интерфейс и способная взаимодействовать посредством его с другими компонентами;
Адаптер
Программная реализация предоставления одного интерфейса через обращение к другому интерфейсу, предоставляемому объектом;
Утилита
Зарегистрированный под определенным интерфейсом и именем объект;
Реестр адаптеров
Реестр, позволяющий зарегистрировать адаптер, и по данному преобразованию одного интерфейса в другой подобрать наиболее оптимальный адаптер;
Реестр утилит
Реестр, позволяющий зарегистрировать объект, и по затребованному интерфейсу и имени объекта найти наиболее подходящий объект;

Сразу обратим внимание на отсутствие в этой модели понятия "Интерфейс-маркер". Дело в том, что оно описывает способ использования интерфейса, а не вводит отдельную сущность. На самом деле, это понятие применимо к ним ко всем, так что избыточно, хотя что-то такое оно описывает.

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

Итак, как не трудно заметить, основное отличие компонентной модели от традиционного ООП - ее экстенсиональность. Компоненты взаимодействуют между собой не в силу своего устройства, как в ООП, а в силу того, что такое взаимодействие объявлено возможным. А уж то, реализовано ли оно было на самом деле, полностью отдается на рассмотрение реализатору компонента.

Брокер запросов:

Брокер запросов - это компонент, который выбирает компонент, который способен обработать запрос, и отслеживает факт выполнения запроса и возврат результатов серверу.

Брокер запросов начинает свою работу с получения от сервера (есть такой компонент, который тоже может менятся) запроса - компонента с интерфейсом IRequest. Обработка этого компонента включает в себя локализацию компонента, который будет обрабатывать запрос. Компоненты локализуются с помощью пути, переданного в запросе, который сходен с обычным путем, но имеет два элемента со специальным синтаксисом: пространство имен и пространство видов.

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

++etc++site
позволяет получить доступ к так называемому сайт-менеджеру, в котором хранятся разные утилиты и настройки сайта Zope. Кроме того, сайт-менеджер предоставляет локальные реестры адаптеров и утилит, позволяя создать свою собственную среду для взаимодействия компонент;
++skin++<ИМЯ СКИНА>
Активирует именованный скин для обработки этого запроса. Упрощенно можно назвать скин визуальным воплощением сайта: его легко переключать и сайт будет иметь множество независимых друг от друга скинов;
++vh++<КУЧА ПАРАМЕТРОВ>
Изменяет среду выполнения запроса так, словно работа идет внутри виртуального сервера. соответственным образом изменяются URL'ы, переменные запроса, видимость компонент, и многое другое;

Основой Zope3, при обработке запросов, как и большинства современных решений такого рода, является паттерн модель-вид-контроллер. В рамках компонентной модели паттерн описывается так:

Модель - компонент, предоставляющий ряд произвольных интерфейсов для взаимодействия с ним;

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

Контроллер - адаптер, обеспечивающий адаптирование пары (модель, запрос), представленной интерфейсами, к компоненту "Вид". Брокер запросов ищет aдаптер в реестре по заданной тройке (модель, запрос, имя вида);

model-view-controller-zope

model-view-controller-zope

Что удобно:

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

Рассказ про MVC позволил ввести одно из ключевых понятий программирования под Zope3 - понятие вида. Вид - это (упрощенно) инструмент просмотра и редактирования объекта. Вид не является составной частью объекта и может не входить в продукт, который поставляет этот объект. Важно лишь то, что вид адаптирует определенный интерфейс объекта к имени, указанному в url (на самом деле все чуть более сложно, но об этом расскажем в описании скинов Скин.txt).

Таким образом, зарегистрировав адаптер какого-либо интерфейса к некоторому имени, мы всегда можем:

  • Для любого компонента, предоставляющего данный интерфейс, получить этот вид в списке видов;
  • Для любого компонента, предоставляющего данный интерфейс вызвать этот вид по имени.

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

Результат запроса:

В конечном итоге, Zope обслуживает (чаще всего) веб-запросы. Результат обслуживания запроса - веб-страница, для генерации которой используются темплейты. Самый известный и распространенный на сегодня такой веб-темплейт - это Zope Page Templates (ZPT).

Суть ZPT состоит в том, чтобы в тексте html-страницы добавить дополнительную разметку, описывающую подстановку в темплейт именованных значений. Практически все языки темплейтов построены так же. Особенностью ZPT является то, что такая дополнительная разметка делается средствами xml: в темплейт вписываются атрибуты и теги, принадлежащие специально выделенному пространству имен xml, благодаря чему размеченная страница выглядит в браузере так же, как и исходная и, в теории, может редактироваться визуальным редактором.

ZPT по ряду причин оказался способом совершенно изменить методику программирования темплейтов в первую очередь потому, что темплейты могут вызывать друг друга и означиваться совместно, а средства программирования оказались настолько гибкими, что можно разделить по разным темлейтам веб-дизайн, способ привязки, содержимое темплейта и при этом каждый темплейт все время остается валидной xml-страницей.

Приведем пример:

            <html> 
                <body> 
                <h1>Please, input Some text:</h1> 
                    <form> <input
                        type="text" name="title" value=""
                        tal:attributes="value request/form/title |
                        string: empty"/>
                    <p tal:content="request/form/title | string:
                      empty">sfsdfsdf</p> 
                    <input type="submit"/>
                </form>
                </body>
            </html>

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

Заключение:

Из вышеизложенного очевидно: центр Zope3 - компонентная модель, без знания которой буквально нельзя сделать ни шагу в Zope3, или же эти шаги будут неправильным. Хотя компонентная модель привлекательна и по своему логична, требуется некоторое ощутимое усилие, чтобы заставить мышление работать в ее рамках.

Как показывает практика, не всем удается этот шаг проделать, но при этом мы всем искренне желаем удачи.

Ссылки на эту статью:

План лекций Семинары
Официальный сайт Zope3 Московская группа изучения реактивного движения The Dream Bot Site noooxml