тиражируемые решения
Т.З. примерно следующее — необходимо иметь некоторый «быстрый старт» для приложений с стандартным функционалом. Дополнительным (и самым «заковыристым») условием является то, что этот стандартный функционал необходимо иметь возможность изменять самым невероятным образом, вплоть до полного отключения и замены своим (специфичным для данного приложения) кодом.
Приведу жизненный пример: есть необходимость делать ОЧЕНЬ похожие приложения. Например интернет-магазины, которые построены на примерно одинаковых схемах данных, бизнес-процессах и тп. Т.е. функционал любого из магазинов примерно идентичен, различается только view слой.
Однако в одном из магазинов цена формируется не из таблицы Prices, а получается по более сложной схеме из хранимой процедуры.
Собственно задача такая — как уменьшить «повторяемость кода» (т.е. отойти от monkey-patching-а) и при этом не потерять полный контроль над кодом.
После непродолжительного анализа существующих решений пришёл к выводу, что существует три вменяемых подхода к решению:
RoR-style (он же maven-archetype)
Весь (практически) код приложения создаётся для приложения в начале разработки автоматически (скриптом, батником, архетипом и тп) а в последствии изменяется под свои нужды в каждом конкретном проекте.
Примером такого подхода являются большинство фреймворков на динамических ЯП: ruby on rails, django, grails,… Кроме того в java существует такой фреймворк как appfuse, использующий maven примерно для тех же целей (автогенерации начального кода).
Плюсы:
- Очень простая структура кода. Нет дополнительных описаний модулей или их конфигурирования. Зачастую — просто код на основном ЯП.
- Скорость работы приложения — см. ниже
Минусы:
- Monkey-patching. Изменения (например bugfix) в основном коде придётся вносить во все проекты вручную.
Java-style
Код разносится по библиотекам и делается очень «настраиваемым» (код в таких библиотеках должен очень хорошо настраиваться и, кроме всего прочего, его можно заменить собственным кодом, специфичным для данного проекта).
Примером такого подхода является например eclipse ide или nuxeo ecm, которые используют equinox (OSGI реализация) для уменьшения «связанности» кода (code decoupling).
Плюсы:
- отсутствие monkey-patching-а (изменения произошедшие в базовой библиотеке автоматически появятся во всех приложениях, его использующих).
Минусы:
- скорость (при использовании такой прослойки как equinox все операции взаимодействия между модулями приложения будут по определению медленнее, чем без использования такой прослойки. Насколько это замедляет приложение на практике сказать сложно — необходимо тестирование).
- дополнительное «оформление» кода (в зависимости от фреймворка описание отдельного модуля потребует как минимум одного «файла описания» этого модуля. Так в nuxeo — это xml файл, в котором описывается модуль, его зависимости от других модулей и методы его «расширения». Т.е. то, как его можно сконфигурировать или отключить.
Специфичное ручное тиражирование
Наверное всем знакомое разнесение кода по библиотекам… Это когда ручками, без всяких «методов и концепций» а так — как бог на душу положит и архитектура позволит… Для Java кода — это использование Interface-ов и применение паттерна plugin, для view слоя — это написание чего-нибудь типа customViewHandler-а и так далее.
Плюсы:
- Не надо ничего изучать, не надо применять новые фреймворки. Весь код «специфичен» для данной области (будь то core или view или ещё что).
Минусы:
- Неуниверсальность. Для частного случая сложно предсказать заранее можно ли будет придумать «вынесение кода в библиотеку» или нет. А если будет возможно вынести код, то возможно это потребует нестандартного (не привычного) стиля написания кода или дополнительного его описания.
Заключение
В заключение хотелось бы спросить у аудитории — кто какой метод использует и насколько успешно?