Международная конференция разработчиков
и пользователей свободного программного обеспечения

What the Zope Component Architecture is and how we used it to solve the consultingware problem

Albertas Agejevas, Вильнюс, Литва, UAB „Programuotojų artelė“, alga@pov.lt

В докладе кратко представлена компонентная архиректура Zope и продемонстрировано, как она была использована для решения проблемы консалтингового ПО. Также рассмотрены альтернативные пути решения проблемы.

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

Компонентная архитектура Zope (ZCA) — это наиболее распространенный независимый продукт сообщества программистов Zope. Вкратце, это расширение языка Python, предоставляющее свойство адаптации. Оно предоставляет единый метод решения проблем расширяемости (pluggability) и конфигурации. ZCA предоставляет абстракции интерфейсов, адаптации (подбор адаптера по интерфейсам кортежа аргументов, имени и запрашиваемому интерфейсу), и служб (англ. utility, подбор службы по запрашиваемому интерфейсу и имени, в сущности синглтон).

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

Процесс оценки каждого работника разбит на части, называемые секциями. Это может быть самооценка, оценка 360 градусов, формулировка целей на последующий год и т.п. Каждая секция реализована как адаптер, который адаптирует данные работника на данный год и предоставляет деловую логику соответствующей части процесса. Секция в свою очередь адаптируется в представление (view), которое отображает и обрабатывает web-формы.

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

wf = IWorkflow(subject)

Адаптер, который вызывается в этом случае, это клозура, описаная следующим образом:
def cycle_specific(interface, adapts=ISubjectCycleData):
  @adapter(adapts)
  @implementer(interface)
  def getCycleSpecific(context):
    name = IPDRConfiguration(context).adapter_names[interface]
    return getAdapter(context, interface, name=name)
  return getCycleSpecific

getCycleSpecificWorkflow = cycle_specific(IWorkflow)


Сначала находится конфигурация текущего цикла субъекта, и из нее достается имя адаптера IWorkflow (допустим, это “foo2010”), и адаптация выражается как getAdapter(subject, Iworkflow,name=“foo2010”), а эта адаптация возвращает уже конкретную реализацию этого адаптера для этого цикла.

По сути, адаптеры подбираются на пару (контекст, цикл), то есть вместо выборки имени адаптера из цикла можно было бы использовать мультиадаптер от этой пары. Так же можно для каждого цикла использовать отдельный регистр адаптеров, организованный как локальный сайт (zope.app.site), или статически описаный посредством пакета z3c.baseregistry.

Такая архитектура системы позволяет несложно изменять поведение системы из года в год, заменять секции новыми версиями, держать в одном дереве кода конфигурации всех клиентов и тестировать их всех в один запуск системы тестов.

Материалы к докладу