Как сохранить одинаковые фрагменты кода в нескольких проектах [закрыто]

9

Я инди-разработчик, работающий над несколькими проектами Android. У меня проблемы с поддержанием одинаковой функциональности в разных проектах. Например, три моих приложения используют одни и те же 2 класса; Поскольку это разные проекты, когда мне нужно внести изменения в эти классы, мне нужно сделать это три раза. Есть ли простое решение этой общей проблемы?

user65721
источник
Как это не реальный вопрос?
Андре Фигейредо

Ответы:

15

Разделяйте общий код в библиотеку и включайте библиотеку в проекты.

Как разработчик Android, вы, вероятно, используете Java. Подумайте об использовании инструмента управления зависимостями, такого как Maven или Ivy .

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

Механическая улитка
источник
2
+1 за управление зависимостями. Должны быть приличные варианты для всех популярных языков.
Адриан Шнайдер
11

Управление версиями. Git. Git Подмодули.

Поместите ваши проекты под контроль версий, используя dvcs, такие как git или mercurial и т. Д. Поместите общий код в подмодуль в git. Используйте субмодуль в проектах, которые в нем нуждаются. Когда вы обновляете субмодуль, можете вытянуть изменения в другие проекты с помощью одной команды.

Хакан Дериал
источник
1
-1: Это действительно «евангельская реклама» определенного продукта под маской ответа на вопрос. Сначала я проголосовал за этот ответ, но, перечитав вопрос, решил, что ответ на самом деле правильный ответ на другой вопрос.
Mattnz
1
-1 также. Я запутался в том, как это лучше, чем в общей библиотеке. Это похоже на злоупотребление git, потому что вы абсолютно отказываетесь делать библиотеку
TheLQ
5
Ну, Git это просто инструмент для использования. Я использую это, я доволен этим. Вы можете использовать его или отказаться от него. Дело в том, что это решает проблему. Я не утверждаю, что это ЕДИНСТВЕННОЕ решение проблемы.
Хакан Дериал
1
Это описывает рабочий подход: извлечение библиотеки запрашивает некоторую работу, которая может быть или невозможна при временных ограничениях OP, поэтому у этого подхода есть свои преимущества.
Франческо
2
+1 Спасибо за ссылку! Если совместно используемый компонент находится в активной разработке, это решение имеет (ИМХО) очевидные преимущества по сравнению с решением совместно используемой библиотеки.
JanDotNet
5

Никто еще не упомянул обоюдоострый меч, поэтому я добавлю свои 2 цента. Если у вас есть несколько проектов, и все они совместно используют некоторый повторно используемый код, в соответствии с хорошими практиками / принципами программирования (например, DRY), вы должны разместить код в одном глобальном месте и структурировать его таким образом, чтобы он мог использоваться всеми ваши проекты без каких-либо изменений. Другими словами, определите интерфейсы, чтобы они были общими и достаточно общими для всех.

Есть несколько вариантов сделать это: 1) Создать базовый проект, от которого зависят другие. Этот проект может создать бинарный дистрибутив, который используют другие проекты. 2) Потяните модель с открытым исходным кодом в вашей организации. Общий код должен быть его собственной ветвью кода, а другие проекты извлекают код таким же образом, как если бы вы брали исходный код из любой OSS в сети.

Теперь вот где меч входит ...

Поместить код в общее место, от которого зависят другие проекты / люди, может быть довольно дорого. Допустим, у вас есть кусок кода и 4 других проекта зависят от него. Один из ваших клиентов, который использует проект A, находит ошибку, и вам нужно исправить ее. Вы спешите с ремонтом, и этот клиент счастлив. Но вы только что изменили некоторый код, от которого зависят 3 других проекта. Вы перепроверяли все это, чтобы убедиться, что не были введены граничные условия?

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

Если ваши проекты находятся на разных циклах выпуска, вам нужно быть еще более осторожным в управлении общим кодом. Вы не можете просто вносить изменения в общий код, потому что проект B нуждается в новой функциональности, если у вас есть 3 дня до вырезания окончательного изображения для проекта C.

Я не говорю, что общая библиотека не является правильным решением. Я решительный сторонник СУХОГО, и раньше я создавал и поддерживал общий код и продолжаю это делать. Просто хотел показать, что простое использование кода будет иметь свои собственные расходы.

Если вы единственный, кто повторно использует этот код, это не так плохо. Если у вас есть команда инженеров, и они начинают использовать общий код, затраты возрастают еще больше. Если другие участвуют, ожидайте, что помещение кода в общую библиотеку займет в 3 раза больше времени, чем требуется, чтобы привести его к точке, когда вы думаете, что она «завершена». Вам необходимо: а) сделать библиотеку более надежной для защиты от всевозможных крайних условий и недопустимого использования, б) предоставить документацию, чтобы другие могли использовать библиотеку, и в) помочь другим людям отлаживать, когда они используют библиотеку таким образом, что вы не ожидал, и ваша документация не охватывает их конкретного случая использования.

Несколько предложений, которые я могу предложить:

  1. Использование общего кода в автоматических модульных тестах может иметь большое значение и дать вам некоторое представление о том, что когда вы вносите изменения, вы не просто ломаете какой-то другой проект.
  2. Я бы только поместил очень стабильную функциональность в общий код. Если в прошлом году вы написали урок для управления таймером, и вы не меняли его в течение 9 месяцев, а теперь у вас есть 3 других проекта, для которых требуются таймеры, то, конечно, это хороший кандидат. Но если бы вы просто что-то написали на прошлой неделе, ну ... у вас не так много вариантов (и я ненавижу копировать / вставлять код, вероятно, больше, чем следующий парень), но я бы дважды подумал о том, чтобы сделать это общим.
  3. Если фрагмент кода тривиален, но вы использовали его в нескольких местах, возможно, лучше откусить пулю, оставить DRY в покое и оставить несколько копий живыми.
  4. Иногда стоит не просто поместить общий код в общее место, чтобы все ссылались на него. Но лучше относиться к общему коду как к своему собственному релизу с версиями, датами выпуска и всем остальным. Таким образом, проект C может сказать: «Я использую общую библиотеку v1.3», и если проекту D требуется новая функциональность, вы оставляете v1.3 в одиночку, выпуск v1.4 и проект C не затрагиваются. Имейте в виду, НАМНОГО, НАМНОГО дороже рассматривать общий код как свой собственный продукт, а не просто проверять его в общем месте.
DXM
источник
1

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

СУХОЙ принцип гласит, что должен быть единый авторитетный источник правды. Это диктует использование единого источника хранилища для всей программной логики без дублирования; файлы организованы для содействия обмену и повторному использованию документов.

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

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

:-)

Единый репозиторий будет вашим единственным авторитетным источником. Процесс сборки для каждого проекта копирует все файлы, используемые этим проектом (и только эти файлы), в промежуточное местоположение, а затем строит из этого промежуточного местоположения. (Unison или другой подобный инструмент можно использовать для перемещения дельт вместо целых файлов).

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

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

Уильям Пейн
источник