Dokumentowanie decyzji projektowych – o ADR i RFC

Opublikowano Kategorie ArchitekturaCzas czytania 15min

O wartości dokumentacji przekonujemy się zwykle wtedy, gdy jej nie ma. W takiej sytuacji pozostaje nam rozpytanie kogoś starszego stażem w projekcie. Alternatywa to przeszukanie historii Gita, przy okazji modląc się, że ten, kto wprowadzał dane zmiany, napisał dobry changelog.  Ale wcale nie musi tak być.

W tym artykule przedstawię Ci dwa typy dokumentów, które mają dużą wartość i które można zgrabnie wpleść w proces wytwarzania oprogramowania. Dowiesz się, czym są Architecture Decision Records (ADR) i Request For Comments (RFC), kiedy i w jakim celu powstają, co powinny zawierać i dlaczego powinniśmy je tworzyć.

Architecture Decision Record – ADR

ADR to dokument opisujący istotne decyzje architektoniczne. ADR opisuje kontekst problemu i rozważane warianty rozwiązania problemu. Częścią ADR jest opisanie ostatecznej decyzji wraz z uzasadnieniem, dobrych i słabych stron wybranego rozwiązania, a także dobrych i słabych stron odrzuconych rozwiązań.

Mając podstawową wiedzę o ADR, należy odpowiedzieć na pytania: kiedy je tworzyć, z jakich powodów, kto, w jaki sposób i co dokładnie powinien zawierać?

Kiedy i dlaczego?

Głównym celem tworzenia ADR-ów jest utrwalanie powodów decyzji w projekcie. Nie ma programisty, który w projekcie trwającym dłużej niż rok czy dwa zapamiętałby aspekty wszystkich ważnych decyzji projektowych. Przeniesienie wniosków do dokumentu sprawia, że można do nich wrócić w dowolnym momencie.

Tworzenie ADR warto rozpocząć, gdy w projekcie pojawia się istotne wyzwanie architektoniczne, szczególnie wtedy, gdy rozważamy kilka alternatywnych rozwiązań. Dokument może powstawać równolegle z analizą problemu, stopniowo nabierając kształtu w miarę poznawania kontekstu i konsekwencji. ADR powinien trafić do review, gdy jest gotowy i gdy jesteśmy w stanie obronić naszą decyzję. Review powinno upewnić nas, że nic nie przeoczyliśmy.

Tworzenie ADR-ów post factum lub wręcz po implementacji jest moim zdaniem mniej efektywne. Po pierwsze, będąc już po analizie problemu, możemy zapomnieć o części aspektów, które braliśmy pod uwagę w trakcie analizy. Również jeśli decyzja została już podjęta, to prawdopodobnie będziemy wobec niej mniej krytyczni. Przez to może bardziej zależeć nam na obronie podjętej decyzji niż na faktycznej analizie problemu (Covering Your Assets anti-pattern). Po trzecie tworzenie dokumentu post factum sprawia, że review takiego dokumentu mija się z celem. Co więcej, co jeśli review wykaże, że decyzja była błędna? Z drugiej strony lepszy taki ADR, niż gdyby nie miało go być wcale.

Niezależnie od skali projektu, moim zdaniem ADR-y warto tworzyć zawsze. Nawet jeśli robimy projekt do szuflady, to taki dokument może za jakiś czas być przydatny. Tworzenie ADR-ów ma szczególnie dużo sensu w długo żyjących projektach. Również w projektach z licznym zespołem lub dużą rotacją, dobrze jest dopilnować, by ADR-y powstawały przy każdej istotnej decyzji projektowej.

Kto i w jaki sposób?

ADR może tworzyć każdy, kto ma do rozwiązania problem na poziomie architektonicznym. Zwykle będzie to jednak ktoś z większym doświadczeniem. Przed utworzeniem pierwszego ADR-a warto upewnić się, jak wygląda ten proces w naszej organizacji, tzn. czy istnieje jakiś szablon, gdzie daną decyzję umieścić oraz kto powinien ją zweryfikować.

ADR-y powinny być napisane w prosty i przejrzysty sposób. To nie ma być rozprawka napisana kwiecistym językiem, tylko mięsisty, stanowczy i zwięzły dokument oparty na faktach. Mogą to być nawet bulletpointy na zasadzie:

  • Good, because…
  • Bad, because…

W procesie tworzenia ADR-a powinien uczestniczyć nie tylko autor, ale też osoby z odpowiednią ekspertyzą. Nawet jeśli nie będzie to miało miejsca na etapie tworzenia ADR, to dobrym pomysłem jest ich zaangażować na etapie review. Jeśli decyzja ma bezpośredni wpływ na biznes, to warto również zaangażować w ten proces stakeholderów. Ważnym aspektem jest publiczny dostęp do ADR w ramach projektu. Dostęp do logów z decyzjami powinna mieć każda osoba zaangażowana w projekt.

Pytanie „w jaki sposób” jest moim zdaniem najmniej istotne. Może to być dowolne narzędzie pozwalające na tworzenie i zamieszczanie dokumentów dostępnych dla każdego członka projektu. Powinno to być narzędzie pozwalające na wejście w dyskusję i krytyczną ocenę ADR-a. Może to być Google Docs, dedykowany tooling, czy Git (o którym powstaje moja książka). Osobiście preferuję Gita i pliki Markdown. Jest prosty w użyciu i zawiera komplet informacji o każdej zmianie w dokumencie: opis, autora i datę. Trzymanie ADR-ów w Markdown pozwala w prosty sposób na połączenie ich z pozostałą dokumentacją projektową. Co więcej, jeśli ADR przechodzi przez pull requesta i code review, to mamy dodatkową informację kto i kiedy tego ADR-a zatwierdził.

Niemniej jednak znacznie ważniejszy jest sam proces tworzenia ADR-ów niż wykorzystane w tym celu narzędzia. Ważne jest też zachowanie spójności i trzymanie wszystkich decyzji podjętych w ramach danego projektu w jednym miejscu.

Co powinien zawierać ADR?

Jedna z moim zdaniem najważniejszych wytycznych, to by ADR dotyczył dokładnie jednej decyzji projektowej/problemu architektonicznego. Jeśli w podobnym czasie podejmujemy kilka powiązanych decyzji lub jedna z nich składa się z kilku faz bądź decyzje się uzupełniają, ADR-y możemy wzajemnie zlinkować.

Umieszczanie wielu decyzji w jednym ADR prowadzi do chaosu. Problemem może być już samo znalezienie interesującego nas fragmentu ADR-a. Kolejny problem to brak separacji poszczególnych aspektów wpływających na konkretne decyzje.

Zawartość ADR-a powinien definiować wcześniej zdefiniowany szablon. Dzięki temu autor uzupełni komplet informacji. Myślę, że nie ma większego sensu, by rekomendować jakiś konkretny szablon. Na końcu artykułu w podlinkowanych materiałach znajdziesz wiele przykładów, którymi możesz się zainspirować.

Niezbędnym elementem ADR-a jest kontekst: wymagania, aspekty biznesowe, stan projektu, założenia, ograniczenia, problemy, a także wymogi i ograniczenia formalne. Innymi słowy, w ADR zamieszczamy wszystko, co ma wpływ na decyzję. Dzięki temu przyszły czytelnik łatwiej zrozumie sytuację, w której ADR powstał.

Kolejnym kluczowym elementem ADR-a jest uzasadnienie podjętej decyzji. Bez ADR-ów to właśnie  „why” jest tym brakującym elementem. To, jaka decyzja została podjęta, widać w kodzie. Dokumentując „why” należy wskazać, które czynniki były decydujące. Kluczowe jest również opisanie korzyści wynikające z podjętej decyzji, jej wady oraz ryzyka. W tym miejscu powinniśmy również opisać alternatywne podejścia oraz ich plusy i minusy. Jeśli nasza decyzja opiera się o inne ADR-y, również zachęcam, by je zlinkować.

W ADR polecam zamieścić wszelkie materiały, które wykorzystaliśmy w trakcie badania danego problemu. Linki do artykułów, książek czy innych dokumentów stanowią dużą wartość dodaną ADR-a. Również, jeśli w trakcie prac nad ADR-em tworzyliśmy prototypy w kodzie czy wykorzystaliśmy pseudokod, to warto zamieścić jego kluczowe fragmenty w treści dokumentu.

ADR powinien być opatrzony datą stworzenia. Dokument tworzymy na podstawie wiedzy i doświadczeń dostępnych w danym momencie. Optymalna w naszej opinii decyzja podjęta w danym momencie czasu może być zupełnie błędna za jakiś czas. Na przestrzeni czasu wybrane aspekty danej decyzji mogą się również dezaktualizować np. nasza wiedza, koszty, decyzje biznesowe czy dostępność specjalistów w danym obszarze. Mając znacznik czasu powstania decyzji mamy pełniejszy obraz sytuacji. Dobrze również, by tytuł ADR-a jednoznacznie wskazywał, czego dotyczy.

ADR powinien jednoznacznie definiować swój stan. Na przykład: Zaakceptowany, Odrzucony, Unieważniony itp. Przykładowe stany ADR-ów można znaleźć w tym dokumencie.

Co jeśli ADR okaże się błędny?

Dokumentowanie decyzji pokazuje swoją wartość również w momencie, gdy dojdziemy do wniosku, że podjęta decyzja jest błędna. Dzięki ADR-om możemy po czasie wrócić do decyzji i przeanalizować ją z nowej perspektywy. Nawet jeśli nie przyniosła negatywnych skutków, warto ją ponownie ocenić. Być może po czasie będziemy w stanie spojrzeć na dany problem z innej perspektywy. Każda z modyfikacji powinna zawierać jej datę i dodatkowy kontekst.

Decyzja podjęta w ADR powinna być niemutowalna. Jeśli zmieniamy decyzję, powinno to skutkować powstaniem nowego ADR-a. Powinien on wskazywać na poprzedni i uzupełniać jego braki.

Celowo mówię o niemutowalności decyzji, a nie samego dokumentu ADR. Moim zdaniem jest akceptowalne dodawanie kontekstu, przykładów czy linków do istniejących już ADR-ów wraz z krótkim uzupełnieniem, o ile nie zmienia to ostatecznej decyzji. To dość powszechny przypadek, gdy faktyczne skutki decyzji poznajemy po czasie. W przypadku zmiany decyzji zalecam, by dodać w starym ADR-ze informację, że został nadpisany.

RFC – Request for Comments

RFC zwykle kojarzone są z formalnymi dokumentami tworzonymi przez inżynierów, gdzie spisane zostały standardy konkretnych rozwiązań. Przykładem może być RFC 2616 opisujący protokół HTTP.

W tym artykule skupię się jednak na definicji RFC nieco bliższej codziennej pracy programisty. RFC, o którym piszę w tym artykule, to lekki dokument projektowy opisujący pomysł (motywację, rozwiązanie, wpływ na istniejący kod) i służy do dyskusji przed implementacją. Możesz również trafić na nazwę Design Docs. Stanowią one zachętę do dyskusji i sposobem na zebranie informacji zwrotnej od reszty zespołu. Jednocześnie sama dyskusja również stanowi wtedy część dokumentacji projektowej.

O ile ADR opisuje już podjęte decyzje architektoniczne, tak RFC to narzędzie do prowadzenia dyskusji. Celem RFC jest również większe zaangażowanie zespołu w dyskusję niż w przypadku ADR. Można wręcz powiedzieć, że RFC to dyskusja podobna do tych, które każdego dnia toczą się na callach i komunikatorach typu Teams czy Slack. Główna różnica jest taka, że w przypadku RFC zostanie po niej ślad w historii projektu.

ADR zwykle dotyczy decyzji o znaczeniu strategicznym (np. wybór architektury komunikacji), RFC może być operacyjne (np. zmiana stylu kodu, podejścia do testów itp.).

Kiedy i dlaczego?

RFC tworzy się w przypadkach, gdy chcemy wprowadzić jakąś zmianę w projekcie i czujemy, że potrzebujemy to przedyskutować w szerszym gronie. Jak nie masz pewności, czy tworzyć RFC, czy nie to… nigdy nie żałowałem, że napisałem jakiś dokument. Za to kilkukrotnie żałowałem, że jakiegoś dokumentu nie napisałem.

RFC najlepiej tworzyć przed implementacją, zwłaszcza gdy zmiana dotyczy publicznych interfejsów lub wpływa na innych członków zespołu. Tworzenie dokumentu po wdrożeniu to już raczej opis gotowego rozwiązania, a nie przestrzeń do dyskusji. Poza tym, co jeśli przedstawione rozwiązanie zostanie odrzucone w dalszej dyskusji?

Nie oznacza to jednak, że nie warto tworzyć prototypów walidujących nasze założenia. Prototyp może odpowiedzieć na pytania i rozwiać wątpliwości znacznie szybciej niż teoretyczne dyskusje.

Gergely Orosz w The Software Engineer’s Guidebook opisuje również sytuacje, gdzie RFC może powstawać już po implementacji. Ja jednak nie jestem fanem takiego podejścia. Pomija ono istotny etap feedbackowania decyzji i analizy alternatyw. Z drugiej strony takie RFC nadal jest wartościową dokumentacją projektową i lepsze takie niż żadne.

Głównym celem powstawania RFC jest ułatwienie sobie życia. Przykładowo, wprowadzamy do projektu potrzebny nam komponent, który potencjalnie może zostać wykorzystany w wielu innych miejscach. Przedyskutowanie ewentualnych potrzeb innych członków zespołu i przypadków użycia może wpłynąć na ostateczną implementację. Dzięki temu możemy np. uniknąć kosztownego refaktoru, gdy okaże się, że wybrana przez nas implementacja nie nadaje się do wykorzystania w innych miejscach.

RFC pozwala również skorzystać z wiedzy i umiejętności reszty zespołu. Każdy członek zespołu ma inne doświadczenia i specjalizacje. RFC to świetna okazja, by z tej wiedzy skorzystać i się nią dzielić. Wspólna analiza tematu pozwala na wypracowanie rozwiązania szybciej i lepiej niż gdybyśmy to robili samodzielnie. Podobnie jak ADR, RFC stanowią świetne źródło informacji o historii projektu dla nowych osób w projekcie.

Tworząc dokumentację projektową, zmuszamy się do przelania myśli na tekst. Nie zliczę, ile razy, spisując jakieś wnioski lub decyzje dochodziłem do wniosku, że są bez sensu. Dokumentując swoje pomysły, już na wczesnym etapie możemy wyeliminować te najmniej sensowne. Dokumentowanie pozwala nam również ograniczyć „klepanie kodu”. Jeśli tak jak ja masz tendencję, by najpierw kodzić, a potem myśleć, to koniecznie spróbuj zacząć pisać RFC. Zobaczysz, jak łatwo zaczniesz wyłapywać luki w pomysłach, które bez dokumentacji już pewnie byłyby w trakcie implementacji.

Kto i w jaki sposób?

W większości pokrywa się to z tym, co opisałem w ramach ADR. Moim zdaniem RFC może tworzyć każdy, kto wie jak. Uważam też, że każdy, kto chce, powinien móc wnosić feedback w ramach RFC (nie ma głupich pytań). Historia powstawania RFC, podobnie jak ostateczna decyzja, powinna być publiczna w ramach projektu.

Co powinien zawierać RFC?

Podobnie jak w przypadku ADR warto, by zawartość RFC definiował szablon. Dzięki temu utrzymamy dokumenty w spójnej i kompletnej formie. Jeśli go jednak nie ma, to nic straconego, napisz bez szablonu lub stwórz własny.

Design docs are informal documents and thus don’t follow a strict guideline for their content. Rule #1 is: Write them in whatever form makes the most sense for the particular project.

Having said that, a certain structure has established itself as really useful.

Industrial Empathy – Design Docs at Google

Dobrze, by RFC miał tytuł jasno definiujący problem oraz datę utworzenia. Podobnie jak przy ADR, jest ona istotna w pełnym zrozumieniu procesu decyzyjnego.

Nieodłącznym elementem RFC jest nakreślenie samego problemu. Opisując problem, należy pamiętać o dołączeniu kontekstu, motywacji oraz wszystkich istotnych szczegółów. Ta część RFC powinna odpowiadać na pytania „what” i „why”.

Kolejnym elementem jest punkt wyjścia w dyskusji, czyli propozycja rozwiązania oraz analiza jego zalet, wad i zagrożeń. Bazując na pierwszej propozycji, można wprowadzać do niej usprawnienia lub proponować alternatywy. W tym miejscu warto uwzględnić wszystkie użyteczne w dyskusji załączniki, takie jak kod, pseudokod, zrzuty ekranu, linki, diagramy, materiały, książki itp.

W przypadku dłuższych procesów decyzyjnych zachęcam, by przygotować podsumowanie zawierające najistotniejsze wątki i wnioski.

Podsumowanie

Tworzenie ADR-ów i RFC nie musi być smutnym obowiązkiem. To okazja do dzielenia się wiedzą, ograniczania „tribal knowledge” i wspólnego wypracowywania rozwiązań, które w dłuższej perspektywie oszczędzają czas, pracę i nerwy. Efektem ubocznym jest dokumentacja, która wraz z wiekiem projektu tylko zyskuje na wartości.

Daj znać czy u Ciebie w projekcie tworzy się ADR-y i RFC i jakie masz przemyślenia na ten temat.

Źródła i materiały dodatkowe

Dominik Szczepaniak

Zawodowo Senior Software Engineer w CKSource. Prywatnie bloger, fan włoskiej kuchni, dobrej kawy i miłośnik jazdy na rowerze.

Inne wpisy, które mogą Cię zainteresować

Przygotuj się lepiej do rozmowy o pracę!

Odbierz darmowy egzemplarz e-booka 106 Pytań Rekrutacyjnych Junior JavaScript Developer i realnie zwiększ swoje szanse na rozmowie rekrutacyjnej! Będziesz też otrzymywać wartościowe treści i powiadomienia o nowych wpisach na skrzynkę e-mail.

Dlaczego warto?

  • 👉 Ponad 1000 pobrań e-booka!
  • 👉 60 stron pełnych pytań i zadań praktycznych. Pytania i zadania pochodzą z faktycznych procesów rekrutacyjnych.

E-booka odbierzesz korzystając z formularza poniżej 👇

Okładka e-booka - Kolejna książka o Gicie

Subskrybuj
Powiadom o
guest

0 komentarzy
Najwięcej głosów
Najnowsze Najstarsze
Opinie w linii
Zobacz wszystkie komentarze