Как организовать параллельную работу над несколькими версиями приложения?
Планируется разработка достаточно сложного веб-приложения на PHP. Особенность приложения в том, что оно будет выпускаться в виде нескольких версий (5-10 штук) для разных клиентов. На 70% функционал у всех версий будет совпадать, а остальные 30% будут отличаться (функционал, допиленный до конкретных клиентов). Отличия достаточно сильные для того, чтобы их можно было просто конфигурировать в файле конфигурации. Разные версии - это не разный набор разрешенных функций, а одни и те же функции, ведущие себя по разному (разный код). Причем на этапе проектирования непонятно, какие части приложения будут различаться. Теоретически абсолютно любой компонент приложения может потребоваться допилить для конкретного клиента. И это могут быть PHP скрипты, JS скрипты, CSS....
Все версии будут эксплуатироваться и поддерживаться параллельно. Приложение будет постоянно дорабатываться, обрастая новым функционалом. Вопрос, какие есть методики для разработки и поддержки ПО с несколькими версиям?
Появилась мысль сделать одно базовое веб-приложение. А для каждого клиента сделать отдельную директорию, файлы в которой, "перекрывают" файлы в базовом приложении. Т.е. сначала пытаемся считать файл из клиентской директории (PHP, JS, CSS), а если его там нет, то ищем файл в базовой. Ну и покрыть все тестами, чтобы при доработке базового приложения не сыпались клиентские версии.
Конечно, были мысли использовать расширения базовых php-классов для реализации модифицированного поведения. Но, как я сказал, изменения могут затронуть вообще любую часть системы, и ставить фабрики классов вообще везде - не хочется. Да и это не решит проблем с JS и CSS.
Мой вопрос, какие есть хорошие подходы для решения этой проблемы?
Расширения базовых классов действительно не лучший подход. Наследование на основе файлов (поиск в директории клиента, если нет - то выше) - это вообще не подход для php, но вполне подход для css/js. Точкой входа является клиентский каталог, css импортирует файлы ядра и перекрывает/расширяет что нужно.
Хороший подход для php - контейнеры зависимостей и сервис-локаторы, когда вы можете в клиентском коде подменять все что хотите из ядра. Заодно тестирование упрощается. Вообще Ваша задача абсолютно типична для любой кастомизируемой разработки, лучше бы взять хороший фреймворк типа симфони и использовать его архитектурные решения. Это как раз тот случай, когда изобретение велосипеда очень дорого потом встанет.