Jesteśmy organizacją składającą się z około 200 programistów, którzy pracują nieprzerwanie nad jednym produktem (używając kontroli wersji Git), która ma zostać wydana w określonym terminie.
Ze względu na ogromną liczbę programistów staramy się tworzyć zespoły „międzyfunkcjonalne” z około 10 programistami w każdym zespole, co daje około 20 zespołów programistycznych w organizacji.
Ponieważ chcielibyśmy utrzymywać stale „wysoki standard” (co oznacza, że gdy deweloper robi pull, produkt powinien przynajmniej być kompilowalny itp.) Produktu w głównym repozytorium, chcielibyśmy użyć pewnego rodzaju bramek jakości.
Nie jestem pewien, jak sformułować pytanie, ale zastanawiam się, czy mógłbym uzyskać porady na temat metodologii programowania dla tak dużej grupy programistów pracujących nad jednym produktem.
Naszym zdaniem jednym końcem spektrum jest umożliwienie każdemu deweloperowi bezpośredniego przypisania się do głównego repozytorium, jednak obawiamy się, że z powodu dużej liczby programistów / zatwierdzeń, że „główne repozytorium” może być ciągle w fazie zepsucia, z powodu nie możemy mieć wymagającej „bramki jakości” dla każdego zatwierdzenia.
Drugi koniec spektrum może przypominać (sądzimy, że robi to Linus Torvalds / Linux) strukturę drzewa lub piramidy, w której „główne repozytorium” ma tylko trzy źródła ściągania, te trzy mają garść zaufanych źródeł pobierania itp. Uważamy jednak, że przy takiej strukturze zmiany wymagają długiego łańcucha, aby wejść do „głównego repozytorium”. Dodatkowo, jeśli wystąpi konflikt scalenia, problem wyląduje na innym deweloperze niż na „pierwotnym deweloperze”.
Biorąc pod uwagę wszystkie te podstawowe informacje i opinie, w jaki sposób możemy nauczyć się i przeczytać zalecane metodologie programowania dla tak wielu programistów? Jak duże organizacje (Microsoft, Facebook, Ubuntu itp.) Kształtują swój rozwój?
Odpowiedzi:
Z pewnością powinieneś rozważyć podzielenie produktu na moduły z zespołem (-ami) interfejsu łączącym te moduły razem w produkt. To z kolei oznaczałoby podział repozytoriów w celu dopasowania do partycjonowania i hierarchii modułów. Jeśli okaże się, że nie możesz tego zrobić, projekt prawdopodobnie zatrzyma się w wyniku scalenia, biorąc pod uwagę liczbę programistów.
Jeśli planujesz używać Gita do kontroli wersji, polecam użycie systemu sprawdzania kodu (takiego jak Gerrit ) w celu poprawy przejrzystości i zapewnienia jakości dla każdego repozytorium. W ten sposób wszystkie prace musiałyby zostać zatwierdzone przed połączeniem z jakimkolwiek wiarygodnym repozytorium. W tym scenariuszu sensowne jest przyznanie niektórym zaufanym osobom uprawnień do wypychania z repozytorium w ramach systemu przeglądu kodu do innego repozytorium (również w ramach systemu przeglądu kodu). Przy prawidłowym zastosowaniu powinien to być szybki i bardzo korzystny proces, który nie utrudnia procesu rozwoju.
Jeśli chodzi o weryfikację kompilacji, potrzebny byłby serwer ciągłej integracji (CI), którego celem jest automatyczna kompilacja i weryfikacja kodu. Przez weryfikację kodu rozumiem, że kod pomyślnie się kompiluje i testy są udane. Infact Jenkins (CI Server) można połączyć z systemem przeglądania kodu Gerrit w ramach etapu weryfikacji Gerrit , w pełni automatyzując proces.
Oprócz tych narzędzi integracji ważne jest dążenie do częstej integracji w ramach metodologii programistycznej, aby zminimalizować czas łączenia.
Warto zastanowić się nad procesem programowania zwinnego, takim jak Scrum, którego celem jest rozbicie złożonego produktu na porcje przyrostu produktu (zwane Sprintami). Zapewni to możliwości integracji między repozytoriami.
źródło
Oczywiście, mając 200-osobowy zespół programistów, musisz mieć jakąś hierarchiczną strukturę. Osoba fizyczna lub niewielka grupa osób podejmuje decyzje dotyczące projektu oprogramowania. Twój proces rozwoju powinien to odzwierciedlać: potrzebujesz przeglądów kodu i testów, aby upewnić się, że tworzone oprogramowanie rzeczywiście odpowiada temu, co chciałeś stworzyć (a także ze względu na jakość).
Nawet małe zespoły potrzebują liderów, którzy poprowadzą zespoły i przejrzą ich pracę podczas opracowywania poszczególnych komponentów. Powinny to być również procesy kontroli jakości na poziomie zespołu.
Tak, powinieneś przestrzegać hierarchicznej struktury w odniesieniu do repozytorium. Ma to na celu dopasowanie ogólnej struktury hierarchicznej projektu.
Poszczególne elementy powinny być budowane i testowane do pewnego poziomu adekwatności, zanim nawet pomyślisz o ich złożeniu. Umożliwienie 200 osobom bezpośredniego zaangażowania w główny projekt byłoby chaosem. Powinieneś mieć osobne obszary dla każdej grupy, w których poszczególne osoby mogą zatwierdzać swoje zmiany na co dzień, bez wpływu na główną wersję projektu.
Bardzo dobrze jest, jeśli „zmiany wymagają długiego łańcucha, aby wejść do głównego repozytorium”, ponieważ ten łańcuch pozwala zapewnić jakość. Może wydawać się szybszy, jeśli wszystkie zmiany od razu zostaną zastosowane w głównym repozytorium, ale w rzeczywistości będzie to po prostu ogromny ból głowy, ponieważ będziesz miał ciągle wadliwą i nieużyteczną główną wersję oprogramowania.
Dobrą rzeczą jest również to, że „jeśli wystąpi konflikt scalenia, problem wyląduje na innym programatorze” - w szczególności to programista wyższego poziomu powinien decydować, jak rozwiązać konflikt.
źródło
Kiedy masz coś dużego i (w konsekwencji) niemożliwego do zarządzania, wyjściem jest podzielenie go na mniejsze i łatwe do zarządzania części.
Istnieje kilka kroków, które pomogą ci lepiej utrzymać zespół i projekt:
podziel funkcjonalność na moduły. Funkcjonalność należy podzielić na maksymalnie maksymalnie niezależne moduły, stosując zasady wysokiej kohezji, niskiego sprzężenia i inwersji zależności. Pierwsza zasada pomoże ci stworzyć logicznie spójne moduły. Drugi pomoże utrzymać te moduły tak niezależne, jak to możliwe. Trzeci pomoże w jednoczesnym rozwijaniu modułów zależnych (jeśli moduł A zależy od modułu B, B powinien zapewnić interfejs, z którego A może korzystać, nawet gdy B nie jest całkowicie gotowy).
mieć przejrzystą dokumentację. Kiedy tak wielu ludzi pracuje razem, rzeczy można łatwo zapomnieć lub źle zrozumieć. Dlatego należy zwrócić szczególną uwagę na całą dokumentację, od wymagań po rozwiązania architektoniczne.
ludzie do zadań (nigdy zadań dla ludzi). Po podzieleniu funkcjonalności na mniejsze zestawy, utwórz zespoły do pracy nad tymi zestawami. Tworzenie zespołów będzie na tym etapie łatwiejsze, ponieważ już wiesz, nad czym każdy zespół ma pracować. A zadania takie jak przegląd kodu byłyby wykonywane wewnątrz każdego zespołu.
przejrzysty system zadań. Każdy z 200 programistów powinien wyraźnie wiedzieć nad czym pracować. Pomoże Ci to śledzić, co zostało już zrobione, nad czym pracuje każda osoba i ile pracy pozostało.
kontrola źródła. (Myślę, że jest to dobrze opisane w innych odpowiedziach)))
I wreszcie, spróbuj stworzyć tak prostą strukturę zespołów i modułów, jak to możliwe. Tak dużego projektu nie stać na złożoność.
źródło
Oprócz innych odpowiedzi sugerujących strukturę hierarchiczną: oznacza to, że będziesz musiał zaplanować punkty „integracji” w czasie, w którym skupia się całkowicie na przesunięciu kodu w górę w hierarchii i „złożeniu go w całość”. Nie różni się to zbytnio od mniejszych projektów z końcową fazą, w której nie wykonuje się żadnej innej pracy poza testowaniem i naprawą błędów, tylko częściej. Ponieważ pracujesz w dużej grupie, dążąc do wysokich standardów, większość tego (nastrój) zapewne już istnieje.
źródło
Oprócz odpowiedzi hotpotato (która jest bezpośrednio na znaku IMHO), sugerowałbym także implementację niektórych bram kontroli źródła, jak sugerujesz. Kiedy przenieśliśmy duży zespół i bazę kodu do git dla SCM, zdecydowaliśmy się zastosować tak zwaną metodę „życzliwego dyktatora”, podobną do opisanego modelu.
W tym scenariuszu istnieje wiele różnych gałęzi pełnej bazy kodu, które są regularnie aktualizowane z gałęzi źródłowej, ale odpowiedzialność za promowanie kodu w bardziej widocznych / publicznych obszarach spoczywa na jednej osobie (lub małej grupie osób) i zazwyczaj związany z procesem przeglądu kodu. Dzięki dobrze zorganizowanej strukturze rozgałęzień może to NAPRAWDĘ dobrze działać. Aby uzyskać więcej informacji, sprawdź ten link .
źródło
Pracowałem nad ogromnym systemem, który miał kilkuset programistów pracujących nad nim jednocześnie z około 150 milionami SLOC. To było na komputerze mainframe, więc nie mówimy o Visual Studio, ale zasady można nadal przyjąć.
Przede wszystkim, jeśli używasz Javy, zdecydowanie powiedziałbym, że użyj Maven. Jeśli używasz VS, możesz również użyć Nuget, chociaż nie jestem pewien, czy jest jeszcze dostępny z Maven (jest też nieco inny). Korzystanie z takiego systemu pozwoli ci wyciągnąć zależności i pozwolić im działać indywidualnie. Będziesz miał skrypt kompilacji, który pobierze odpowiednie zależności i skompiluje jako partię.
Biorąc pod uwagę, że nie zadajesz bezpośrednio pytania, ale pytasz o metodologię, powiem ci, jak poradził sobie mój poprzedni pracodawca.
System został podzielony na klastry . Klastry reprezentowały obszary biznesowe i obszary infrastruktury systemowej. Nie zamierzam ich wymieniać, ale w przypadku dużego biznesu detalicznego możesz pomyśleć o takich rzeczach, jak marketing, operacje detaliczne, operacje online, zamówienia, dystrybucja. Infrastruktura systemu reprezentowała takie rzeczy, jak klienci i bezpieczeństwo. W każdym klastrze znajdowały się komponenty . Korzystając z poprzedniej analogii, możesz wziąć pod uwagę na przykład elementy bezpieczeństwa - pojedyncze logowanie, usługi katalogowe, audyt, raportowanie itp. Każdy komponent miał w sobie swoje względne procedury.
Jako przestrzeń nazw lub pakiet miałbyś na przykład Organisation.Security.DirectoryServices. Zawierając całą logikę w odpowiednich obszarach, zespoły pracowały dość autonomicznie. Oczywiście miały miejsce duże projekty wymagające wkładu wielu zespołów, ale były one w dużej mierze sprawne.
Mam nadzieję, że to pomoże.
źródło