Я работаю над большим программным проектом, который специально адаптирован для различных клиентов по всему миру. Это означает, что у нас может быть 80% кода, который является общим для разных клиентов, но также и много кода, который должен меняться от одного клиента к другому. В прошлом мы занимались разработкой в отдельных репозиториях (SVN), и когда начинался новый проект (у нас мало, но крупных клиентов), создавался другой репозиторий, основанный на том, какой предыдущий проект имел наилучшую основу кода для наших нужд. Это работало в прошлом, но мы столкнулись с несколькими проблемами:
- Ошибки, которые исправлены в одном репозитории, не исправляются в других репозиториях. Это может быть проблемой организации, но мне трудно исправить и исправить ошибку в 5 разных репозиториях, учитывая, что команда, обслуживающая этот репозиторий, может находиться в другой части мира, и у нас нет тестовой среды также не знаете своего графика или требований, которые у них есть («ошибка» в одной стране может быть «функцией» в другой).
- Функции и улучшения, сделанные для одного проекта, которые также могут быть полезны для другого проекта, теряются или если они используются в другом проекте, часто вызывают большие головные боли при слиянии их из одной базы кода в другую (поскольку обе ветви могли разрабатываться независимо в течение года ).
- Рефакторинг и улучшения кода, сделанные в одной ветви разработки, либо теряются, либо приносят больше вреда, чем пользы, если вам нужно объединить все эти изменения между ветвями.
Сейчас мы обсуждаем, как решить эти проблемы, и до сих пор придумали следующие идеи, как решить эту проблему:
Сохраняйте разработку в отдельных ветках, но лучше организуйте, имея центральный репозиторий, в который объединяются общие исправления ошибок, и все проекты объединяют изменения из этого центрального репозитория в свои собственные на регулярной (например, ежедневной) основе. Это требует огромной дисциплины и больших усилий для слияния ветвей. Так что я не уверен, что это сработает, и мы сможем сохранить эту дисциплину, особенно, когда время ограничено.
Отказаться от отдельных ветвей разработки и иметь центральное хранилище кода, где живет весь наш код, и выполнять нашу настройку, имея подключаемые модули и параметры конфигурации. Мы уже используем контейнеры Dependency Injection для разрешения зависимостей в нашем коде, и мы следуем шаблону MVVM в большей части нашего кода, чтобы четко отделить бизнес-логику от нашего пользовательского интерфейса.
Второй подход кажется более элегантным, но у нас есть много нерешенных проблем в этом подходе. Например: как обрабатывать изменения / дополнения в вашей модели / базе данных. Мы используем .NET с Entity Framework, чтобы иметь строго типизированные сущности. Я не понимаю, как мы можем обрабатывать свойства, которые требуются для одного клиента, но бесполезны для другого клиента, не загромождая нашу модель данных. Мы думаем о решении этого в базе данных с помощью спутниковых таблиц (имеющих отдельные таблицы, в которых наши дополнительные столбцы для конкретной сущности живут с отображением 1: 1 на исходную сущность), но это только база данных. Как вы справляетесь с этим в коде? Наша модель данных находится в центральной библиотеке, которую мы не сможем расширить для каждого клиента, использующего этот подход.
Я уверен, что мы не единственная команда, борющаяся с этой проблемой, и я шокирован, когда нашел так мало материала по этой теме.
Итак, мои вопросы следующие:
- Какой у вас опыт работы с высоко настраиваемым программным обеспечением, какой подход вы выбрали и как он работал для вас?
- Какой подход вы рекомендуете и почему? Есть ли лучший подход?
- Есть ли хорошие книги или статьи на эту тему, которые вы можете порекомендовать?
- У вас есть конкретные рекомендации для нашей технической среды (.NET, Entity Framework, WPF, DI)?
Редактировать:
Спасибо за все предложения. Большинство идей совпадают с теми, которые у нас уже были в нашей команде, но очень полезно увидеть опыт, который вы имели с ними, и советы, как лучше их реализовать.
Я все еще не уверен, по какому пути мы пойдем, и я не принимаю решение (в одиночку), но я передам это в моей команде, и я уверен, что это будет полезно.
На данный момент тенор, похоже, представляет собой единый репозиторий с использованием различных пользовательских модулей. Я не уверен, что наша архитектура соответствует этому или сколько мы должны вложить, чтобы привести его в соответствие, поэтому некоторые вещи могут некоторое время жить в отдельных репозиториях, но я думаю, что это единственное долгосрочное решение, которое будет работать.
Итак, еще раз спасибо за все ответы!