Jak zachować te same fragmenty kodu w wielu projektach [zamknięte]


9

Jestem niezależnym programistą pracującym nad wieloma projektami na Androida. Mam problem z utrzymaniem tej samej funkcjonalności w różnych projektach. Na przykład trzy moje aplikacje używają tych samych 2 klas; ponieważ są to różne projekty, kiedy muszę wprowadzić zmiany w tych klasach, muszę to zrobić trzy razy. Czy istnieje proste rozwiązanie tego rodzaju powszechnego problemu?


Jak to nie jest prawdziwe pytanie?
Andre Figueiredo

Odpowiedzi:


15

Rozdziel udostępniony kod na bibliotekę i włącz bibliotekę do projektów.

Jako programista Androida prawdopodobnie korzystasz z Javy. Zastanów się nad użyciem narzędzia do zarządzania zależnościami, takiego jak Maven lub Ivy .

Efektem ubocznym jest to, że pomoże to utrzymać separację obaw poprzez wymuszenie modułowości. Koszt jest taki, że rozdzielenie może zająć trochę pracy; korzyścią jest lepsza konserwacja w przyszłości. Ponadto, jeśli kiedykolwiek zdecydujesz się na to, możesz zwolnić bibliotekę oddzielnie (komercyjnie lub jako oprogramowanie typu open source) ze swoich aplikacji.


2
+1 za zarządzanie zależnościami. Powinny istnieć przyzwoite opcje dla wszystkich popularnych języków.
Adrian Schneider,

11

Kontrola wersji. Git Submodules Git.

Umieść swoje projekty pod kontrolą wersji, używając dvcs takich jak git lub mercurial itp. Umieść udostępniony kod w submodule w git. Użyj submodułu w projektach, które go potrzebują. Po zaktualizowaniu submodułu można wyciągnąć zmiany do innych projektów za pomocą jednego polecenia.


1
-1: To jest naprawdę „ewangeliczna promocja” określonego produktu pod przykrywką odpowiedzi na pytanie. Początkowo głosowałem za tą odpowiedzią, ale po ponownym przeczytaniu pytania zdecydowałem, że odpowiedź jest właściwie właściwą odpowiedzią na inne pytanie.
mattnz

1
-1 również. Nie wiem, jak to jest lepsze niż biblioteka współdzielona. Wydaje się, że to tylko nadużywanie gita, ponieważ absolutnie nie chcesz tworzyć biblioteki
TheLQ

5
Cóż, git to tylko narzędzie do użycia. Używam tego, jestem z tego zadowolony. Możesz go użyć lub odmówić. Faktem jest, że rozwiązuje problem. Nie twierdzę, że jest to jedyne rozwiązanie problemu.
Hakan Deryal

1
Opisuje to podejście robocze: rozpakowanie biblioteki wymaga pracy, która może być lub nie jest możliwa w ramach ograniczeń czasowych PO, więc to podejście ma swoje zalety.
Francesco

2
+1 dzięki za link! Jeśli komponent współużytkowany jest w trakcie aktywnego opracowywania, to rozwiązanie ma oczywiste korzyści (IMHO) w porównaniu z rozwiązaniem biblioteki współdzielonej.
JanDotNet,

5

Nikt inny nie wspomniał jeszcze o obosiecznym mieczu, więc dodam 2 centy. Jeśli masz wiele projektów i wszystkie mają wspólny kod wielokrotnego użytku, zgodnie z dobrymi praktykami / zasadami programowania (na przykład DRY), powinieneś umieścić kod w jednym globalnym miejscu i ustrukturyzować go w taki sposób, aby mógł być wspólny dla wszystkich twoje projekty bez żadnych modyfikacji. Innymi słowy, zdefiniuj interfejsy, które będą na tyle ogólne i wystarczająco powszechne, aby pasowały każdemu.

Istnieje kilka opcji: 1) Utwórz projekt podstawowy, na którym inni będą polegać. Ten projekt może utworzyć dystrybucję binarną, która będzie wykorzystywana przez inne projekty. 2) Wyciągnij model open source w swojej organizacji. Niech wspólny kod będzie jego własną gałęzią kodu, a inne projekty ściągną kod w taki sam sposób, jak weźmiesz kod źródłowy z dowolnego OSS online.

Teraz tutaj jest miecz ...

Umieszczenie kodu we wspólnym miejscu, od którego zależą inne projekty / ludzie, może stać się dość kosztowne. Powiedzmy, że masz kawałek kodu i od tego zależą 4 inne projekty. Jeden z Twoich klientów korzystający z projektu A znajduje błąd i musisz go naprawić. Pospiesz się, a klient jest zadowolony. Ale właśnie zmodyfikowałeś kod, od którego zależą 3 inne projekty. Czy przetestowałeś je wszystkie, aby upewnić się, że nie zostały wprowadzone żadne warunki brzegowe?

Wspólny kod musi być również tworzony znacznie ostrożniej, a interfejsy modułów muszą być znacznie lepiej zaprojektowane, ponieważ kod ten musi pomieścić nie jednego, ale 4 klientów, a każdy z nich może po prostu używać tego kodu z niewielką różnicą.

Jeśli twoje projekty są w różnych cyklach wydań, musisz być jeszcze bardziej ostrożny w zarządzaniu wspólnym kodem. Nie można po prostu wprowadzić zmian we wspólnym kodzie, ponieważ projekt B potrzebuje nowej funkcjonalności, jeśli dzieli Cię 3 dni od wycięcia ostatecznego obrazu dla projektu C.

Nie twierdzę, że wspólna biblioteka nie jest właściwym rozwiązaniem. Jestem silnym zwolennikiem DRY i wcześniej stworzyłem i wspierałem wspólny kod i nadal to robię. Chciałem tylko powiedzieć, że zwykłe upowszechnianie kodu będzie miało własne koszty.

Jeśli jesteś jedynym, który ponownie używa tego kodu, nie jest tak źle. Jeśli masz zespół inżynierów, którzy zaczną używać wspólnego kodu, wydatki wzrosną jeszcze bardziej. Jeśli zaangażowane są inne osoby, spodziewaj się, że umieszczenie kodu we wspólnej bibliotece zajmie 3 razy więcej czasu niż potrzeba, aby doprowadzić go do punktu, w którym uważasz, że jest „kompletny”. Będziesz musiał: a) uczynić bibliotekę bardziej odporną na ochronę przed wszelkiego rodzaju warunkami brzegowymi i nieprawidłowym użytkowaniem, b) dostarczyć dokumentację, aby inni mogli korzystać z biblioteki oraz c) pomóc innym osobom w debugowaniu, gdy korzystają z biblioteki w sposób nie przewidziałem, a twoja dokumentacja nie obejmowała konkretnego przypadku użycia.

Kilka propozycji, które mogę zaoferować:

  1. Posiadanie wspólnego kodu objętego automatycznymi testami jednostkowymi może przejść długą drogę i dać ci poczucie, że dokonując zmiany, nie zepsułeś innego projektu.
  2. Umieściłbym tylko bardzo stabilną funkcjonalność we wspólnym kodzie. Jeśli napisałeś w zeszłym roku zajęcia z zarządzania timerem i nie zmieniłeś tego od 9 miesięcy, a teraz masz 3 inne projekty, które potrzebują timerów, to upewnij się, że to dobry kandydat. Ale jeśli właśnie napisałeś coś w zeszłym tygodniu, cóż ... nie masz tak wielu opcji (a ja nienawidzę kopiowania / wklejania kodu prawdopodobnie bardziej niż następnego faceta), ale pomyślałbym dwa razy o upowszechnieniu tego.
  3. Jeśli fragment kodu jest trywialny, ale używałeś go w kilku miejscach, być może lepiej ugryźć kulę, zostawić DRY w spokoju i pozwolić żyć wielu kopiom.
  4. Czasami opłaca się nie umieszczać wspólnego kodu we wspólnej lokalizacji i zachęcać wszystkich do odwoływania się. Ale raczej traktuj wspólny kod jako własny, który można wydać wraz z wersjami, datami wydania i wszystkim. W ten sposób projekt C może powiedzieć: „Używam wspólnej biblioteki v1.3”, a jeśli projekt D potrzebuje nowej funkcjonalności, zostawiasz v1.3 w spokoju, wypuszczasz v1.4 i projekt C nie ulega zmianie. Należy pamiętać, że WIELKIE, DUŻO droższe jest traktowanie wspólnego kodu jako własnego produktu, a nie tylko sprawdzanie go we wspólnej lokalizacji.

1

Jest to wyidealizowane rozwiązanie i może wymagać trochę wysiłku, aby zacząć działać.

Zasada DRY stanowi, że powinno istnieć jedno wiarygodne źródło prawdy. Wymaga to użycia jednego repozytorium źródłowego dla całej logiki programu, bez powielania; pliki zorganizowane w celu promowania udostępniania i ponownego wykorzystywania dokumentów.

Pragmatyczne wymagania komunikacji w rozproszonym, wielozadaniowym środowisku sugerują, że powinno istnieć wiele niezależnych repozytoriów, po jednym dla każdego projektu lub współpracy.

Podchodziłbym do tego problemu, poddając się nieuniknionemu: będziesz musiał zastosować oba podejścia jednocześnie, a my wykorzystamy skrypty i automatyzację, aby wyeliminować fakt, że podejścia są sprzeczne.

:-)

Jedno ujednolicone repozytorium będzie Twoim jedynym wiarygodnym źródłem. Proces kompilacji dla każdego projektu spowoduje skopiowanie wszystkich plików używanych przez ten projekt (i tylko te pliki) do lokalizacji pośredniej, a następnie kompilację z tej lokalizacji pośredniej. (Unison lub podobne narzędzie może służyć do przenoszenia delt zamiast całych plików).

Te pośrednie lokalizacje mogą być używane jako lokalne kopie robocze dla zestawu wtórnych, pochodnych lub dalszych repozytoriów. Skrypty przechwytujące po zatwierdzeniu w autorytatywnym repozytorium zaktualizują wszystkie pośrednie lokalizacje, a dla każdego z kolei sprawdzą, czy się zmieniły, i dokonają tego samego zatwierdzenia w odpowiednim repozytorium wtórnym, jeśli zmiana zostanie wykryta.

W ten sposób wiele wtórnych repozytoriów jest zsynchronizowanych z pojedynczym autorytatywnym repozytorium źródłowym, a proces kompilacji zapewnia, że ​​repozytoria wtórne zawierają wszystkie (ewentualnie współdzielone) dokumenty i inne pliki, które są potrzebne do pomyślnej kompilacji. Co najważniejsze, proces tworzenia i kompilacji gwarantuje, że pliki są edytowane w jednym miejscu i tylko w jednym miejscu, a wszystkie kopie są spójne i aktualne.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.