Przyspieszanie współpracy i opracowywanie aplikacji Agile za pomocą składnikyzacji
Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019
Twój produkt jest pomyślny, twoja organizacja rozwija się i nadszedł czas, aby skalować bazę kodu w górę, aby dopasować ją do tego sukcesu. Podczas skalowania w poziomie ostatnich 2–3 zespołów pracujących w jednej bazie kodu na jednym produkcie możesz zadawać pytania, takie jak:
Jak moje zespoły mogą efektywnie udostępniać składniki wielokrotnego użytku?
Jak mogę umożliwić moim zespołom funkcji szybkie iterowanie bez przechodzenia na pracę innych zespołów?
Jak mogę dać moim zespołom autonomię, aby iterować w tempie, które jest dla nich odpowiednie?
Zespoły na dowolnym etapie mogą skorzystać z rozważenia tych pytań. Jeśli jesteś utworzonym zespołem ze starszą bazą kodu, możesz zadać te same pytania, co poproszono Cię o dostarczenie większej wartości, szybciej niż kiedykolwiek. Niezależnie od sytuacji, składnikyzacja może pomóc w utworzeniu bazy kodu, która skaluje się do rozmiaru zespołu i szybkości dzisiejszego programowania.
W tym artykule dowiesz się, w jaki sposób kompozycja binarna za pośrednictwem usługi Azure Artifacts może pomóc w zarządzaniu zależnościami zewnętrznymi, oprogramowaniu typu open source i izolowanym udostępnionym składnikami.
Składniki i kompozycja
Składnikyzacja to proces dzielenia i organizowania produktu na odrębne składniki. Większość projektów platformy .NET ma już pewne pojęcie składników w postaci projektów w ramach rozwiązania. Na przykład podstawowa witryna internetowa może składać się ze składnika frontonu, składnika dostępu do danych i składnika magazynu danych/modelu.
Kompozycja źródłowa
Wraz ze wzrostem produktu rozwiązanie i model projektu mogą stać się nieefektywne. Integrowanie zmian trwa dłużej i jest trudniejsze do scalenia, kompilacja staje się wolniejsza, a składniki zaczynają rosnąć z jednego projektu do wielu projektów. Ogólnie rzecz biorąc, jest to punkt, w którym zespoły zaczynają rozbijać te zestawy powiązanych projektów w oddzielne rozwiązania.
Po przejściu do pojedynczego rozwiązania sposób składnikyzacji staje się interesującym pytaniem. Zaczęliśmy od kompozycji źródłowej, gdzie każdy składnik jest przywołyny za pośrednictwem odwołania do projektu w programie Visual Studio. Kompozycja źródłowa jest możliwa tak długo, jak źródło znajduje się w jednej granicy kompozycji: pojedyncze rozwiązanie w jednym repozytorium źródłowym.
Niestety, te odwołania do projektu zaczynają się rozpadać, gdy jest zaangażowanych wiele rozwiązań. W tym momencie, gdy rozwiązanie A zależy od rozwiązania B, musi odwoływać się do skompilowanych plików binarnych (takich jak biblioteki DLL) utworzonych przez rozwiązanie B — jest to kompozycja binarna.
W związku z tym te pliki binarne muszą teraz zostać skompilowane i udostępnione rozwiązaniu A, zanim będzie można je pomyślnie skompilować. Istnieje kilka sposobów, aby to zrobić:
Możesz je zaewidencjonować w kontroli źródła. W zależności od systemu kontroli źródła pliki binarne mogą szybko dymić rozmiar repozytorium, spowalniając czasy wyewidencjonowania i ogólną wydajność repozytorium. Jeśli zaczniesz pracować w gałęziach, wiele zespołów może wprowadzić ten sam plik binarny w różnych wersjach, co prowadzi do trudnych konfliktów scalania.
Alternatywnie można hostować je w udziale plików, chociaż takie podejście wiąże się z pewnymi ograniczeniami. Udziały plików nie mają indeksu dla szybkich odnośników i nie zapewniają ochrony przed zastąpieniem wersji w przyszłości.
Kompozycja pakietu
Pakiety odpowiadają wielu wyzwaniom związanym z odwoływaniem się do plików binarnych. Zamiast ewidencjonować je w źródle, możesz mieć rozwiązanie B tworzące jego pliki binarne jako pakiety NuGet, które może następnie wykorzystywać inne rozwiązanie A. Jeśli rozwiązanie A i rozwiązanie B są utrzymywane jako oddzielne składniki, gdzie jednoczesne zmiany w A i B są rzadkie, kompozycja pakietów jest doskonałym sposobem zarządzania zależnością A od B. Kompozycja pakietów pozwala B iterować na własną kadencję, podczas gdy A jest wolny do pobierania aktualizacji z B, gdy harmonogram A zezwala, umożliwia wielu zespołom iterowanie i aktualizowanie rozwiązania B bez wpływu na rozwiązanie A (lub inne rozwiązania C lub D).
Jednak kompozycja pakietów ma swój własny zestaw wyzwań. Do tej pory przeanalizowaliśmy prosty przykład. Skalowanie kompozycji pakietów do rozmiaru dużej bazy kodu (np. Windows lub Bing) może powodować szereg wyzwań:
Zrozumienie wpływu zmian powodujących niezgodność w składniku niskim na wykresie zależności staje się bardzo trudne.
Zależności diamentów mogą stać się znaczącym przeszkodą w zwinności. W zależności od rombu składniki B i C zależą od współużytkowanego składnika A, podczas gdy składnik D zależy zarówno od B, jak i C. Gdy składnik A wprowadza nową wersję ze zmianami powodującymi niezgodność, jeśli B aktualizuje nową wersję, ale C nie, D nie może pobrać aktualizacji B bez wprowadzania konfliktu zależności. W tym prostym przykładzie rozmowa z językiem C może być potrzebna do rozwiązania konfliktu. Jednak w złożonym grafie diamenty mogą szybko stać się nierozwiązane.
W przypadku konieczności zastosowania modyfikacji do dwóch składników, które składają się przy użyciu pakietów, cykl iteracji dewelopera staje się znacznie wolniejszy. Jeśli składnik A jest aktualizowany, wymaga ponownego kompilowania, ponownego tworzenia i ponownego publikowania. Następnie składnik B musi zostać zaktualizowany do ostatnio opublikowanej wersji, aby zweryfikować zmiany wprowadzone w składniku A. Zastosowanie kompozycji źródłowej, która umożliwia jednoczesne tworzenie składników A i B, będzie stale dostarczać szybszy cykl iteracji dla deweloperów.
Czego należy użyć
Ogólnie rzecz biorąc, widzieliśmy, że duże zespoły są najbardziej skuteczne, gdy używają kombinacji strategii kompozycji. Aby ułatwić określenie, co jest odpowiednie dla bazy kodu, zacznij od mapowania wykresu zależności produktu i zacznij grupować składniki w zestawy powiązanych składników.
Na przykład może istnieć kolekcja składników tworzących strukturę, a także inny zestaw składników tworzących usługę użytkownika. Następnie dla każdej grupy powiązanych składników zadaj następujące pytania:
Czy mogę przewidzieć częste ewidencjonacje w zestawach, które ustanowiłem dla moich zespołów?
Czy jeden zespół jest odpowiedzialny za cały zestaw?
Czy w przypadku pojedynczego zestawu istnieje współużytkowany cykl wydania?
Z naszego doświadczenia wynika, że używanie kompozycji źródłowej jest najbardziej skuteczne w przypadku powiązanych projektów obsługiwanych przez pojedynczy zespół lub grupę powiązanych zespołów. Z drugiej strony kompozycja binarna jest korzystna dla oprogramowania open source, zależności zewnętrznych (składników z odległych lub odizolowanych zespołów) i niezależnych składników udostępnionych.