Andrew Harmel-Law

Tworzenie architektury oprogramowania

Wspieranie zespołów w podejmowaniu trafnych decyzji

Przekład: Piotr Pilch

Tytuł oryginału: Facilitating Software Architecture: Empowering Teams to Make Architectural Decisions

Tłumaczenie: Piotr Pilch

ISBN: 978-83-289-2752-0

© 2025 Helion S.A.

Authorized Polish translation of the English edition of Facilitating Software Architecture ISBN 9781098151867 © 2025 Andrew Harmel-Law.

This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same.

All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher.

Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji.

Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli.

Autor oraz wydawca dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz wydawca nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce.

Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
helion.pl/user/opinie/twarop_ebook
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.

Helion S.A.
ul. Kościuszki 1c, 44-100 Gliwice
tel. 32 230 98 63
e-mail: helion@helion.pl
WWW: helion.pl (księgarnia internetowa, katalog książek)

- Kup w wersji papierowej

- Poleć książkę na Facebook.com

- Oceń książkę

- Księgarnia internetowa

- Lubię to! » Nasza społeczność

Opinie o książce
Tworzenia architektury oprogramowania

Andrew doskonale rozumie architekturę. Książka jest pełna praktycznej wiedzy opartej na szerokim doświadczeniu, przedstawionej w postaci dobrze napisanej narracji i ukształtowanej w sposób, który dociera do istoty tego, czym jest architektura, a czym nie jest, a także jak ją urzeczywistnić.

— Grady Booch, wyróżniony tytułem IBM Fellow

W najlepszym wariancie architektura oprogramowania jest rozwijana przez wszystkie zaangażowane osoby. Książka napisana przez Andrew przedstawia praktyczny proces, który pozwala zrealizować tę wizję, czyli zaangażowanie szerokiego grona osób i zadbanie o rzetelne rejestrowanie decyzji.

— Martin Fowler, główny naukowiec w firmie Thoughtworks

Fascynujące spojrzenie na często pomijany temat podejmowania decyzji ze szczególnym i dokładnym uwzględnieniem aspektów społecznych. Publikacja polecana dla osób chcących odejść od tradycyjnych scentralizowanych struktur władzy kojarzonych zwykle z architekturą oprogramowania.

— Simon Brown, twórca modelu C4 do wizualizacji architektury oprogramowania

Kontrowersyjnie stwierdzę, że nie wierzę, że „każdy może tworzyć architekturę”. Tworzenie architektury nie jest umiejętnością demonstrowaną przez jedną osobę. Architektura to orkiestracja praktyk, które generują systemowe wsparcie w celu wspólnego i poprawnego myślenia o systemach oprogramowania. W tej książce Andrew przedstawia nam, jakie to są praktyki, dlaczego są ważne i jak je adaptować. Przeczytaj książkę i udowodnij, że się mylę.

— Diana Montalion, architektka systemów, założycielka firmy Mentrix i autorka książki Myślenie systemowe dla programistów

To doskonały przewodnik po zdecentralizowanym i partycypacyjnym procesie podejmowania decyzji architektonicznych, niezbędnym do kierowania ewolucją złożonych systemów opartych w dużym stopniu na oprogramowaniu.

— Ruth Malan, konsultantka ds. architektury w firmie Bredemeyer Consulting

W pośpiechu do przyjęcia strukturalnych i wymagających aspektów metafory architektury często pomijamy to, czym naprawdę ona jest i dla kogo istnieje: dla ludzi. Architektura tworzy przestrzeń do życia i pracy. Definiuje doświadczenia tych, którzy ją zamieszkują.

Architektura powoduje konsekwencje w postaci czasu i kosztów, które wpływają zarówno na tych, którzy tworzą oprogramowanie, jak i na korzystających z niego. W książce Andrew przywraca ten fundamentalny i ludzki aspekt architektury, który tak często bywa pomijany. Przedstawia perspektywy, zasady, procesy i praktyki architektury, które wspierają ludzi, ich pracę i cele, zamiast skupiać się jedynie na technologiach i strukturze technicznej.

— Kevlin Henney, niezależny konsultant w firmie Curbralan

Architektura umożliwiająca szybki przepływ wymaga zarówno „zdecentralizowanego podejmowania decyzji”, jak i „szybkiej informacji zwrotnej na dużą skalę”. Książka pokazuje, jak poruszać się w tej kluczowej, socjotechnicznej przestrzeni. Stanowi spójny i łatwy do zrozumienia przewodnik dla każdego. Gorąco polecam.

— Matthew Skelton, współautor książki Team Topologies oraz prezes i założyciel firmy Conflux

Twoja architektura oprogramowania jest odzwierciedleniem decyzji podjętych podczas jej tworzenia. Andrew wyjaśnia, jak ulepszyć proces podejmowania decyzji leżący u podstaw takiej architektury, a tym samym ją samą, za pomocą technik i procesów opartych na współpracy. Istnieje lepszy sposób na „uprawianie” architektury.

— Jacqui Read, główna architektka, autorka książki Wzorce komunikacji, trenerka i międzynarodowa prelegentka

Zdecentralizowany nadzór był jedną z pierwotnych cech mikrousług, ale co to właściwie oznacza? W tej książce Andrew podejmuje znakomitą próbę odpowiedzi na to pytanie. Uważam, że powinna ona znaleźć się na półce każdego lidera technologicznego.

— James Lewis, dyrektor w firmie Thoughtworks UK oraz twórca oryginalnej definicji mikrousług

Każda firma, z którą współpracowałem, doceniająca szybki przepływ i niezależne zespoły zmaga się z zaufaniem zespołów w kwestii odpowiedzialności za architekturę oprogramowania. Książka napisana przez Andrew dostarcza jasnych wytycznych, jak umożliwić zespołom przejęcie odpowiedzialności za architekturę przy jednoczesnym budowaniu zaufania między zespołami i kierownictwem.

— Kenny Baas-Schwegler, współautor książki Collaborative Software Design, niezależny architekt oprogramowania, lider techniczny i projektant systemów

Miałem zaszczyt uczestniczyć w pierwszym Architecture Advisory Forum i obserwować, jak rodzi się magia. Grupa osób, które nigdy wcześniej ze sobą nie rozmawiały ani się nie znały, szybko i płynnie odnalazła się w przepływie roboczym tego forum. Widziałem, jak podejmowano decyzje techniczne w sposób demokratyczny i odpowiedzialny, a także jak przy braku zgodności rozwiązywano spory przez podejmowanie zobowiązań. Przede wszystkim jednak obserwowałem, jak ludzie w naturalny sposób dążyli do wspólnej strategii i oswajali się z odpowiedzialnością wobec siebie i innych. Książka ta to przełomowy wkład w naszą branżę i chciałbym, aby znalazła się na biurku każdego lidera technicznego.

— Vanessa Formicola, główna inżynierka w firmie Flo Health Inc., międzynarodowa prelegentka, twórczyni społeczności i orędowniczka zmian społecznych

Dostępnych jest wiele książek omawiających najlepsze praktyki z zakresu tworzenia odpowiedniej architektury oprogramowania. To pierwsza tego rodzaju publikacja, która rzeczywiście koncentruje się na najbardziej fundamentalnym czynniku zmiany w architekturze, czyli na ludziach i kulturze.

Książka opiera się na praktycznym podejściu do wspierania zespołów i organizacji w rozwijaniu najlepszych praktyk architektury oprogramowania w bezpieczny i niewykluczający sposób. Każdy lider inżynierii powinien mieć tę książkę w swojej fizycznej lub wirtualnej bibliotece!

— Cassandra Shum, wiceprezeska ds. inżynierii terenowej w firmie RelationalAI

Wiemy, że tylko wtedy, gdy ludzie sami opracowują swoje projekty, pojawia się niezbędna motywacja, odpowiedzialność i zaangażowanie. I nie ma lepszego sposobu niż ten, który Andrew proponuje w tej książce. Architektura jest czymś, na czym wszystkim nam zależy w procesie tworzenia oprogramowania, ale wielu czuje się niekomfortowo, zajmując się nią. To, co Andrew opisuje w książce, to sposób na umożliwienie wszystkim uczestnictwa w tym procesie. Ważniejsze niż kiedykolwiek wcześniej jest to, abyśmy wszyscy brali w nim udział.

— Trond Hjorteland, konsultant ds. technologii informatycznych i praktyk socjotechniczny w firmie Capra Consulting

Mając doświadczenie w praktycznym stosowaniu tych technik, mogę potwierdzić ich skuteczność. Książka stanowi praktyczny i wnikliwy przewodnik dla architektów oprogramowania, którzy muszą radzić sobie z rozproszonymi zespołami, budować zaufanie, wspierać innowacje i opracowywać skalowalne praktyki architektury.

— Noush Streets, wiceprezeska ds. inżynierii w firmie Chainalysis, była dyrektorka ds. technologii w firmie Xapo Bank

Najbardziej kompleksowe opracowanie procesu podejmowania decyzji w ramach tworzenia oprogramowania, jakie dotąd powstało. Jest to lektura obowiązkowa dla wszystkich osób zaangażowanych w projektowanie oprogramowania.

— Sonya Natanzon, dyrektorka ds. inżynierii w firmie Guardant Health oraz międzynarodowa prelegentka

Książka jest pełna przedstawionych w praktyczny sposób doświadczeń i mądrości zdobytych przez całą karierę w dziedzinie architektury oprogramowania. Warta uwagi jest choćby ze względu na szczegółowe omówienie procesu doradztwa. A to tylko jeden z wielu aspektów dotyczących metod budowania fundamentów zaufania i efektywnej pracy przedstawionych w przystępny i swobodny sposób. Przeczytałem książkę od początku do końca, aby pogłębić własne umiejętności.

— JD Carlston, dyrektor ds. inżynierii w firmie Stack Overflow

Książka przedstawia nowe, zdecentralizowane podejście do praktyk architektury oprogramowania. Andrew dostarcza architektom i projektantom praktycznych wskazówek, jak uczestniczyć w procesie doradztwa w kwestii architektury i go usprawniać. Celem jest optymalizacja zdecentralizowanych decyzji architektonicznych opartych na zaufaniu przy zachowaniu odpowiedzialności i spójności.

— Susanne Kaiser, międzynarodowa prelegentka i niezależna konsultantka

W książce zaprezentowano praktyczne i proste podejście do skalowania i demokratyzacji architektury oprogramowania, a także dokonano dogłębnej analizy kwestii dlaczego, co pomoże uniknąć porażki spowodowanej ślepym naśladownictwem.

— Rob Horn, kierownik działu technicznego w firmie Thoughtworks

Innowacyjny przewodnik, który kwestionuje tradycyjne pojęcia z dziedziny architektury oprogramowania. Książka promuje świeże podejście, oparte na różnorodności, niewykluczaniu i empatii. Nie tylko zmienia sposób, w jaki myślimy o architekturze oprogramowania, ale także dostarcza praktycznych strategii wspierania niewykluczania i empatii w praktykach architektury.

— Jen Wallace, główna projektantka w firmie Thoughtworks

Ta wnikliwa książka jest pełna przykładów z życia pokazujących, w jaki sposób podejmować decyzje architektoniczne niezależnie od funkcji pełnionej w zespole. Jako liderka techniczna uznałam ją za szczególnie pomocną w zrozumieniu dynamiki relacji między liderem technicznym i architektem.

— Elena Alina Oanea, liderka techniczna w firmie Thoughtworks

Książka prezentuje podejście socjotechniczne do kwestii architektury oprogramowania, którego świat wymaga coraz bardziej. Andrew jasno objaśnia potrzebę i rolę przywództwa w ramach „praktykowania architektury”. To świetna koncepcja, która podkreśla zarówno różnorodność ról architektonicznych, jak i ich wspólne cechy. Książka nie będzie zbierała kurzu na półce, gdyż będziesz po nią regularnie sięgać w poszukiwaniu praktycznych wskazówek.

— Evelyn van Kelle, współautorka książki Collaborative Software Design, konsultantka ds. zmiany zachowań i myślicielka socjotechniczna

Słowo wstępne

Sposób, w jaki dziś tworzy się oprogramowanie, zmienił się diametralnie od czasu, gdy zaczynałam pracę jako projektantka ponad 20 lat temu.

Zmiany, które zaszły, czyli pojawienie się metodyk Agile i DevOps oraz przejście w ich przypadku od projektu do produktu, wiązały się ze zwiększoną decentralizacją i niezależnością. Obecnie zespoły zazwyczaj same udostępniają swój kod, obsługują własne systemy i decydują, w jaki sposób rozwiązywać potrzeby biznesowe.

Z mojego doświadczenia wynika jednak, że najtrudniejsza do zdefiniowania okazała się rola architekta.

Gdy ponad dekadę temu tworzyłam systemy monolityczne, architekci pracowali w osobnym zespole. Projektowali oni architekturę dla całego systemu, ustalali standardy i wybierali, jaka ma zostać użyta baza danych, język programowania lub mechanizm wdrażania. Jest kilka powodów, dla których takie podejście nie sprawdza się we współczesnych organizacjach zajmujących się inżynierią. Decyzje te stają się wąskim gardłem, blokując postęp zespołów. Ponadto obecnie jest jeszcze mniejsza szansa na to, że jedno rozwiązanie będzie odpowiednie dla wszystkich zespołów.

Jaka jest alternatywa? Można pozwolić zespołom na podejmowanie własnych decyzji architektonicznych, albo przydzielając architektów do bezpośredniej współpracy z nimi, albo czyniąc „architekturę” rzeczą, którą zajmują się osoby na wyższych stanowiskach inżynieryjnych (obok innych obowiązków). Może to jednak prowadzić do znacznego zróżnicowania w przypadku stosowanych metod. Może to być ryzykowne: czy wszystkie różne magazyny danych zaktualizowano i zabezpieczono? Może to także prowadzić do marnowania energii, gdy wiele zespołów boryka się z tymi samymi problemami.

Rozwiązaniem jest opracowany przez Andrew proces doradztwa w kwestii architektury. Zespoły nadal zachowują autonomię w zakresie podejmowania decyzji architektonicznych, ale proces wymaga od nich zasięgania porad u osób, na które mają wpływ dokonywane wybory, oraz u ekspertów. Zmniejsza to ryzyko, że zespoły podejmą decyzje kolidujące ze sobą (lub przynajmniej zrobią to nieświadomie) albo że kilka zespołów będzie musiało rozwiązywać ten sam problem.

Tym, co urzeka mnie w tej książce, jest możliwość rozpoczęcia realizowania opisanego procesu już po przeczytaniu kilku pierwszych rozdziałów. Zachęcam do tego, zgodnie z zaleceniem Andrew, aby zacząć od czegoś niewielkiego (np. od jednego zespołu). Jednakże w przypadku pozostałej części książki przewiduje się, że możesz napotkać trudności, dlatego oferuje ona szereg pomysłów, jak sobie z nimi poradzić. W końcu mamy do czynienia z niewielkim procesem, który pociąga za sobą duże zmiany.

Rzeczywistą istotą propozycji autora jest to, że proces doradztwa w kwestii architektury może kształtować niezbędną kulturę, prowadząc nas w kierunku organizacji, która optymalizuje naukę, autonomię i szybki przepływ wartości. Wiąże się to z dzieleniem się przez niektórych uprawnieniami do podejmowania decyzji, co może być wyzwaniem. Oznacza to także, że inni muszą zacząć decydować i brać odpowiedzialność za swoje wybory, co może być przerażające.

Warto to jednak robić, ponieważ to właśnie członkowie zespołów odpowiedzialni za utworzenie danej opcji najlepiej rozumieją, że stoi przed nimi znacząca decyzja do podjęcia, i to oni poniosą jej konsekwencje.

Byłam znacznie lepiej przygotowana do obsługi mojego systemu w środowisku produkcyjnym, gdy mogłam odejść od opcji implementacyjnych narzuconych mi wcześniej przez kogoś innego. Oznaczało to wybór rzeczy łatwiejszych w obsłudze, w przypadku których więcej osób miało odpowiednie doświadczenie.

Będę polecała klientom ten proces i tę książkę, ponieważ stanowi ona znacznie pełniejszą implementację rzeczy, które sprawdziły się w moim przypadku w przeszłości: pozwól zespołom podejmować decyzje, upewnij się, że rozmawiają z właściwymi osobami, a następnie nie przeszkadzaj im w działaniu. Myślę, że będziesz zaskoczony efektem, jaki to podejście wywrze na Twoją firmę.

— Sarah Wells,
niezależna konsultantka,
autorka książki Enabling Microservice Success
i przewodnicząca konferencji QCon London

Przedmowa

Gdyby dostarczanie oprogramowania polegało wyłącznie na wpisywaniu wierszy kodu, pojedyncze osoby działające osobno mogłyby osiągać te same rezultaty co zespoły o podobnej liczebności i umiejętnościach. Tak jednak nie jest. Zespoły potrafią tworzyć lepsze oprogramowanie i faktycznie je tworzą.

W sporcie oczekuje się, że zdolności i doświadczenie będą zróżnicowane, a każdy odegra swoją rolę. Gdy ludzie z drużyny łączą swoje umiejętności i koncentrują się na wspólnym celu, mają największe szanse na zwycięstwo[1]. Te same zasady obowiązują w zespołach projektantów oprogramowania, w przypadku których celem jest zrównoważone dostarczanie i rozwój odpowiedniej jakości produktu końcowego.

Jako konsultant, projektant i architekt oprogramowania/systemów miałem ogromne szczęście współpracować blisko z kilkoma wyjątkowo utalentowanymi zespołami dostarczającymi oprogramowanie. Widziałem ich członków w akcji, korzystających z wielu różnych stylów architektonicznych, szerokiego zestawu języków programowania, narzędzi i stosów technologicznych, wdrażających rozmaite podejścia i praktyki, działających w ramach wielu różnych środowisk wykonawczych, a także wspieranych przez liczne kultury i organizacje. Nauczyłem się niesamowicie dużo, obserwując ich w trakcie pracy. Byli doskonałymi przykładami koncepcji wysokowydajnych zespołów.

Miałem też szczęście poznać kilku wybitnych architektów oprogramowania, czerpać od nich wiedzę, a gdy szczególnie mi się poszczęściło, pracować z nimi. Podziwiałem ich sposób myślenia, tworzenia, wykorzystywania wiedzy i rozwiązywania problemów. Jednakże to nie te umiejętności czyniły ich wyjątkowymi. Ich geniusz tkwił w tym, jak słuchali, komunikowali się, współpracowali, tworzyli razem z innymi i ułatwiali im pracę. Dzięki temu budowane przez nich architektury z powodzeniem trafiały do realnego świata i działały zgodnie z oczekiwaniami.

Zespoły dostarczające produkty, które nauczyły mnie najwięcej, zawsze potrafiły maksymalnie wykorzystać umiejętności i możliwości jak największej liczby swoich członków przez odpowiednio długi czas. To, co robiły, było zrównoważone i korzystne dla wszystkich. Architekci, od których najwięcej czerpałem, osiągali dokładnie ten sam cel, ale dostarczali tę wartość w ramach wszystkich zespołów. We wszystkich przypadkach potrafili w pełni wykorzystać potencjał oprogramowania.

Co takiego robiły te zespoły, że odnosiły sukcesy? I czego jednocześnie nie realizowały? Stopniowo zacząłem dostrzegać, że najbardziej wydajne zespoły wspierane przez architektów współpracujących w największym zakresie nigdy nie wydawały się negatywnie dotknięte przez niesamowitą złożoność architektur, które budowały i uruchamiały. W rzeczywistości gdy śledziłem tę współpracę, trudno mi było rozróżnić, kto jest architektem, a kto członkiem zespołu dostarczającego. Przenikanie się sposobów myślenia i ról było tak głębokie, że niemal sprawiało wrażenie, jakby wszyscy zajmowali się architekturą.

Tymczasem w najsłabiej działających zespołach rzadko brakowało umiejętności technicznych. Nie brakowało też chęci do pracy jako samodzielnie zarządzający się zespół. Dlaczego zatem jego członkowie ponosili porażkę? Co robili, co im szkodziło? Czego nie realizowali, co mogłoby im pomóc? Jeden kluczowy problem pojawiał się raz za razem: nieudanym zespołom brakowało dwukierunkowej relacji z architekturą. Zamiast tego byli hamowani przez zdystansowanych architektów i ich pilnie strzeżone projekty oraz inne artefakty.

Obserwując zarówno skuteczne, jak i nieskuteczne zespoły oraz architektów, dostrzegłem wzorce w ich sposobach pracy, identyfikując to, co działało, i to, co przeszkadzało. Przy wsparciu innych osób przeprowadziłem eksperymenty, aby sprawdzić, czy można zoptymalizować kluczowe elementy ich wspólnego sposobu myślenia, podejścia i praktyk, które wydawały się czynić ich tak skutecznymi jako kolektyw. W rezultacie udało mi się wyodrębnić zestaw powiązanych ze sobą elementów i innych wniosków, które uczyniły praktyki najbardziej wydajnych zespołów dostępnymi dla wszystkich, co z kolei przywróciło każdemu pełną moc oprogramowania.

Marc Andreesen jest znany ze stwierdzenia „oprogramowanie pożera świat”[2], ponieważ każde oprogramowanie bez wyjątku ma ogromny potencjał. Umożliwia ono realizowanie różnych rzeczy szybciej, taniej i efektywniej. Oprogramowanie pozwala nam robić to, co inaczej byłoby niemożliwe, a nawet niewyobrażalne. Pomimo tego jednak, że ten artykuł został opublikowany (w momencie pisania książki) dziesięć lat temu i była w nim mowa o bliskiej przyszłości, oprogramowanie nie pochłonęło jeszcze wszystkiego na swojej drodze. Dzieje się tak, ponieważ oprogramowanie ma moc, ale jest ona tracona, przejawiając się jako złożoność, sztywność, koszt i marnotrawstwo. Jeśli jednak uda nam się sprostać tym wyzwaniom, ta moc nadal jest dla nas dostępna dokładnie tak, jak była w momencie napisania artykułu.

Mimo tego potencjału mocy zbyt wiele zespołów niechętnie pracuje nad połowicznymi wersjami cudzej wizji, opartej na powierzchownym zrozumieniu problemu, który starają się rozwiązać.

Odpowiedniej jakości oprogramowanie powstaje dzięki spójnym, interdyscyplinarnym zespołom, które rozumieją i mają wpływ na obszar problemu oraz projekty stosowane do uporania się z nim. Jakościowe oprogramowanie odzwierciedla wspólny sposób myślenia i modele mentalne zespołów, które są głęboko kształtowane przez rzeczywistość ich działających systemów. Powinno to być przyszłością i doświadczeniem każdego z nas.

Niestety ta przyszłość jest, parafrazując Williama Gibsona, nierównomiernie rozłożona. Nieraz widziałem, jak architektoniczne metody pracy, struktury organizacyjne i kultury korporacyjne świadomie, a nawet celowo stają na drodze tej zbiorowej sile interdyscyplinarnych zespołów. Paradoksalnie te próby kontroli istnieją właśnie dlatego, że potęga oprogramowania w trybach awaryjnych (słusznie) powoduje obawy. Im bardziej jednak próbowano zarządzać negatywnymi skutkami, tym bardziej utrudniano zastosowanie potencjalnych korzyści.

Książka ma na celu zmianę sposobu, w jaki wspólnie podchodzimy do architektury oprogramowania, aby dać każdemu szansę bycia częścią wysokowydajnego zespołu. Podzielę się praktykami i sposobami myślenia, które sprawdziły się w szerokim zakresie zarówno w przypadku architektów, jak i projektantów. W szczególności architekci nauczą się podejścia opartego na ułatwianiu, które ma potencjał uwolnienia mocy zespołów architektonicznych i tworzonego przez nie oprogramowania. Projektanci dowiedzą się, jak zwiększyć swój udział i wnosić znaczący wkład w dyskusje na temat architektury oprogramowania jako równorzędni partnerzy. Książka pomoże wszystkim, zarówno architektom, jak i projektantom, przejść na to nowe podejście oparte na zestawie podstawowych zasad, które zapewnią drogę do sukcesu niezależnie od indywidualnych okoliczności.

W trakcie lektury będziesz rozwijać swoje umiejętności i zrozumiesz, że kontrola nad swoją architekturą i działającymi systemami jest iluzoryczna. Odkryjesz też potęgę uczenia się i pracy zespołowej, gdy pozwolisz innym działać. Jeśli jesteś architektem, nauczysz się też, jak wspierać zespół, wyzwalając i rozwijając jego potencjał z korzyścią dla wspólnie tworzonej architektury. Jeżeli jesteś członkiem zespołu, dowiesz się, jak zapewniać wkład w architekturę, ucząc się i dzieląc wiedzą, maksymalizując tym samym pozytywny wpływ wszystkich osób. Co być może jest najważniejsze, każdy dowie się, jak kluczowe są bezpieczeństwo i integracja, a także jak fundamentalna jest potrzeba otwartości i zaufania.

Dla kogo jest ta książka?

Książka jest skierowana głównie do dwóch grup, które staram się połączyć: projektantów chcących podjąć kroki w kierunku odpowiedzialności za architekturę oraz architektów poszerzających swój repertuar o umiejętności dotyczące ułatwiania pracy.

„Architekci” w inżynierii oprogramowania

Praca nad książką nauczyła mnie jednej rzeczy: prawie każda organizacja ma inne wyobrażenie o tym, czym zajmuje się „architekt” w dziedzinie oprogramowania. Aby zatem książka miała sens dla moich czytelników, muszę zdefiniować, co mam na myśli, używając tego terminu.

Zamieszanie wynika z faktu, że istnieje wiele różnych archetypów architektów oraz trybów zaangażowania w proces dostarczania i rozwoju oprogramowania. Z tego powodu mówi się o architektach oprogramowania, architektach domenowych, architektach rozwiązań, architektach biznesowych, architektach systemowych, głównych inżynierach, architektach korporacyjnych, architektach z działu informatycznego, głównych architektach i wielu innych[3].

W książce mniej skupiam się na nazewnictwie, a więcej na zakresie odpowiedzialności i kompetencji z dziedziny architektury. Jasne zrozumienie tych kwestii pozwoli Ci przełożyć moje spostrzeżenia na role występujące w Twojej firmie.

Na początku mamy osoby praktykujące architekturę w ramach (i na rzecz) wielu zespołów. Osoby te są zwykle znane jako dopasowani[4] architekci oprogramowania lub rozwiązań, jeśli zgodnie współpracują z wieloma zespołami, oraz jako architekci zespołowi lub liderzy technologiczni, jeżeli są stałymi członkami jednego zespołu. Obie te grupy mają nawet możliwość pisania kodu, który trafia do środowiska produkcyjnego. Jeśli należysz do jednej z nich lub aspirujesz do tego, należysz do pierwszej grupy docelowej odbiorców książki. W książce odnoszę się do tych działań jako do architektury „wewnątrz zespołów”[5].

Na drugim miejscu znajdują się osoby zajmujące się architekturą w ramach zespołów, ale w obrębie pakietów produktów lub programów roboczych. Są one powszechnie znane jako architekci systemowi. Jeśli tworzą kod, jest mało prawdopodobne, aby trafił on do środowiska produkcyjnego. Jeżeli zaliczasz się do tych osób, reprezentujesz drugą grupę docelową odbiorców książki. Odnoszę się w niej do tych działań zamiennie: jako do architektury systemowej oraz architektury między zespołami.

Trzecią grupę stanowią osoby zajmujące się architekturą w skali całej organizacji. Są one powszechnie znane jako architekci korporacyjni, architekci z działu informatycznego lub główni architekci, a ich zakres działania obejmuje wszystkie systemy technologiczne w organizacji, a nie tylko te tworzone wewnętrznie. Jeśli należysz do tej grupy, nie jesteś docelowym odbiorcą książki, choć możesz polecić zajrzenie do niej osobom pełniącym funkcje architektoniczne w ramach pierwszej i drugiej grupy. Opisane tu praktyki pomogą także w realizacji Twoich celów.

Jeśli w nazwie zajmowanego przez Ciebie stanowiska pojawia się słowo architekt, prawdopodobnie możesz ulokować się w jednej lub kilku z tych trzech ról. Być może dotyczy Cię więcej niż jedna z nich. Ważne jest to, żebyś potrafił je interpretować, a także to, abyś wyraźnie rozumiał, do której roli lub ról się odnoszę.

Najprawdopodobniej Twoja firma jest w trakcie adaptowania najnowszych rewolucyjnych rozwiązań z zakresu dostarczania oprogramowania. Nie ma znaczenia to, na jakim etapie tego procesu firma się znajduje. Nie jest też istotne, jaki stosuje się konkretny styl architektoniczny, język lub języki albo środowisko wykonawcze.

Nie musisz się też specjalnie przygotowywać przed rozpoczęciem lektury. Zakładam, że znasz już bolesne szczegóły dotyczące praktyki architektury w Twojej firmie oraz ciemną stronę systemów działających w środowisku produkcyjnym. Jest to wszystko, czego będziesz potrzebował. Całą resztę wiedzy zdobędziesz z tych stron oraz od swoich współpracowników.

Aby ta książka mogła Ci pomóc, proszę, byś był otwarty na doświadczenie zarówno swoje własne, jak i, co równie ważne, Twoich współpracowników. To, czego się nauczysz, zadziała, jeśli będziesz gotowy zmienić swoje podejście oraz dotychczasowe wyobrażenia o tym, jak „robi się” architekturę oprogramowania i jakie są umiejętności oraz doświadczenia innych. Aby to osiągnąć, musisz być otwarty na głęboką i szczerą współpracę z osobami w całej firmie. Musisz być gotowy do nauki, ponoszenia porażek i wyciągania z nich wniosków. Może to być niewygodne, ale jest warte zachodu. Musisz być skłonny zarówno do oddania kontroli, jak i wzięcia odpowiedzialności, analizowania różnych spraw świeżym spojrzeniem, nie zapominając jednocześnie o tym, co już wiesz.

Dlaczego napisałem tę książkę?

Książka Accelerate (O’Reilly) Nicole Forsgren, Jeza Humble’a i Gene’a Kima rzuciła wyzwanie całemu środowisku inżynierii oprogramowania, zachęcając nas do lepszej pracy i zapewniania lepszych rezultatów, a konkretniej rzecz ujmując: do przyspieszenia działań bez wpływu na jakość. Chodzi też o zwiększenie niezależności zespołów bez narażania spójności i jakości uzyskanego systemu.

W odpowiedzi na to wyzwanie eksperymentowałem z zestawem praktyk. Niektóre pochodziły ze świata oprogramowania, a inne z zupełnie innych miejsc. Inspiracją były dla mnie doświadczenia osób, które spotkałem podczas otwartego wydarzenia Java Posse Roundup[6]. Kiedy zacząłem stosować te praktyki w przypadku kolejnych klientów, którzy nie byli gwiazdami rocka, lecz zwykłymi projektantami i architektami, takimi jak Ty i ja, byłem zdumiony, jak dobrze się sprawdzały i jak satysfakcjonujące okazały się dla wszystkich uczestników.

Wiele z tych eksperymentów było następstwem zawirowań spowodowanych pandemią COVID-19. Być może klienci czuli potrzebę wypróbowania nowych i odmiennych podejść, aby dostosować się do niepewnych czasów. Niezależnie od przyczyny przyniosło to fascynujące rezultaty, którymi poczułem się zmuszony podzielić się ze światem. Opublikowałem swoje pierwsze przemyślenia w wątku w serwisie Twitter (https://threadreaderapp.com/thread/1341319003374039040), który został zaskakująco dobrze przyjęty. Niektórzy koledzy z firmy Thoughtworks usłyszeli o moich sukcesach i zapytali, co robię. W odpowiedzi napisałem to, co stało się postem na blogu Martina Fowlera Scaling the Practice of Architecture, Conversationally (https://martinfowler.com/articles/scaling-architecture-conversationally.html). Po jego publikacji byłem ponownie zaskoczony poziomem zainteresowania, jakie wzbudził. Zacząłem o tym mówić na konferencjach i w podcastach. Ludzie zwracali się do mnie zarówno po dalsze porady, jak i po to, by opowiedzieć mi o podobnych podejściach, do których doszli sami, zupełnie niezależnie od tego, co ja robiłem. Inni również eksperymentowali w tej dziedzinie i chcieli o tym rozmawiać.

W tym czasie nadal pracowałem z klientami, implementując różne warianty tego podejścia i ucząc się od innych, którzy robili to samo w swoich firmach. Badałem przyczyny, dla których pewne rzeczy działają, i zwracałem uwagę na sytuacje, w których pojawiały się problemy. Stało się jasne, że można powiedzieć wiele na temat tej fundamentalnie prostej kombinacji elementów. Moje notatki się rozrastały, a metody stawały się coraz bardziej dopracowane. Suma tego, czego się nauczyłem, doprowadziła mnie ostatecznie do napisania książki, którą trzymasz teraz w rękach.

Moją największą nadzieją jest to, że ta książka podtrzyma ducha eksperymentowania, nauki i dzielenia się wiedzą. W moich doświadczeniach najbardziej uderza mnie to, jak w różny sposób elementy i otaczająca je kultura przejawiają się po wprowadzeniu ich w życie. Choć istnieje pewien rdzeń, którego trzeba się trzymać, by w pełni skorzystać z podejścia opisanego w książce, nie ma jednego ścisłego sposobu, aby to zrealizować. Weź to, czego się tutaj nauczysz, i dostosuj do swoich potrzeb. Jeśli choć niewielka część tego okaże się dla Ciebie przydatna, podziel się swoimi doświadczeniami z innymi. Proszę, przekazuj dalej to, czego się nauczyłeś, abyśmy wszyscy mogli z tego skorzystać. Strony społeczności dostępne w witrynie o adresie https://facilitatingsoftwarearchitecture.com/ są przeznaczone właśnie do tego celu.

Struktura książki

Książkę podzielono w następujący sposób:

- W rozdziale 1. omówiono problem stosowania scentralizowanych praktyk architektury w zdecentralizowanym świecie.

- Część pierwsza, „Podstawowe zasady” (rozdziały od 2. do 6.), obejmuje kluczowe aspekty zdecentralizowanego podejścia do architektury, skoncentrowanego na informacji zwrotnej.

- W części drugiej, „Kształtowanie i rozwijanie kultury zdecentralizowanego zaufania” (rozdziały od 7. do 11.), wyjaśniono dynamikę wynikającą z głównego podejścia i wprowadzono szereg elementów wspierających, aby zapewnić jego skuteczność.

- W części trzeciej, „Poruszanie się w środowisku decyzyjnym” (rozdziały od 12. do 14.), powrócono do podstawowych praktyk i przeanalizowano, jak najlepiej zastosować je w swojej firmie.

- I wreszcie w części czwartej, „Umieszczenie elementu społecznego w centrum swojej praktyki architektury” (rozdziały od 15. do 17.), zrobiono krok wstecz, aby przyjrzeć się społecznym aspektom praktyki architektury, które wysuwają się na pierwszy plan, jeśli adaptuje się to podejście. Przedstawiono zarówno pułapki, jak i dobre praktyki.

Konwencje zastosowane w książce

W książce kursywa wskazuje nowe pojęcia, adresy URL, adresy e-mail, nazwy plików oraz ich rozszerzenia.

Ten element identyfikuje wskazówkę lub sugestię.

Ten element oznacza ogólną uwagę.

Materiały uzupełniające

Materiały uzupełniające (dodatkowe ćwiczenia, szablony, dalsze artykuły i przykłady) są dostępne na stronie o adresie https://facilitatingsoftwarearchitecture.com/.

Podziękowania

Pisanie książek okazało się trudniejsze, niż sobie wyobrażałem. Równocześnie to jedna z najbardziej satysfakcjonujących rzeczy, jakie kiedykolwiek zrealizowałem. Dziękuję Dianie Montalion za to, że była przy mnie na każdym kroku, dodając otuchy, gdy czułem, że to niemożliwe, i uspokajając mnie, gdy zbyt się rozpędzałem. Przede wszystkim dziękuję za falę inspirujących sugestii, którą wywołałaś, dostrzegając potencjał tej książki.

Książka traktuje o sile porad, a ja miałem dostęp do najlepszych dotąd doradców technicznych. Pragnę podziękować Vanessie Formicoli, Alinie Balusescu, Jen Wallace, Trondowi Hjortelandowi i Robowi Hornowi za tak wiele poświęconego czasu, dzielenie się doświadczeniem i wiedzą ekspercką. Dzięki Wam książka stała się zdecydowanie znacznie lepsza.

Jedną z pierwszych osób, które w całości przeczytały (prawie) ukończony artykuł, była Sarah Wells. Dziękuję Ci za zrozumienie tego, co chciałem przekazać i w jaki sposób starałem się to zrobić, a także za zwięzłe ujęcie tego w słowie wstępnym.

Inspiracja dla tego podejścia pochodziła z trzech źródeł. Ruth Malan była pierwszą osobą, która mnie zainspirowała. Ruth, Twoje spostrzeżenia, otwartość jako domyślna postawa, budowanie społeczności, niepohamowany entuzjazm i współpraca dały mi nowe spojrzenie na praktykę architektury. Dziękuję Ci za to.

Bruce Eckell i Java Posse byli drugim źródłem inspiracji. Dopóki nie przebrnąłem przez koloradzkie śniegi na mój pierwszy udział w Java Posse Roundup, nigdy nie widziałem, co może się wydarzyć, gdy stworzy się przestrzeń i pozwoli ludziom na samoorganizację. Rozmowy, które odbyłem w Crested Butte na przestrzeni lat, skłoniły mnie do zastanowienia się, jak wiele mogę zrobić, usuwając się z drogi, a mimo to nadal będą dziać się wspaniałe rzeczy. Bruce, Dick, Carl, Tor, Joe i inni, których poznałem na tych spotkaniach, ukazali mi to. Dziękuję Wam wszystkim.

Alberto Brandolini był trzecią inspiracją. Alberto, wątpię, czy zdajesz sobie sprawę, ile bezsennych nocy spędziłem po tym, jak powiedziałeś mi, że „to założenia projektantów trafiają do środowiska produkcyjnego”. Próba znalezienia sposobu na praktykowanie architektury, która uwzględniałaby tę myśl, doprowadziła mnie do tego miejsca. Dziękuję Ci.

Inspiracja już była, ale pierwszy raz wszystkie elementy książki połączyły się ze sobą na początku pandemii COVID-19. Gdy gromadziliśmy się na spotkaniach za pośrednictwem narzędzia Zoom, miałem szczęście współpracować z Pete’em Hunterem i resztą zespołu firmy OpenGI. Jak potwierdza to książka, Pete często dostrzegał siłę i dynamikę tego podejścia wyraźniej niż ja. Pete, dziękuję Ci za pracę razem ze mną nad wczesną wersją tego materiału. Dziękuję również wszystkim z firmy OpenGI za umożliwienie nam eksperymentowania z Wami.

Dziękuję też Melowi Mitchellowi i reszcie zespołu firmy Thoughtworks, którzy pracowali ze mną nad tym samym projektem. Wy także przyczyniliście się do powstania wczesnej wersji tego podejścia, ale to jedna osoba w szczególności powiedziała mi, żebym „to zapisał”. Mel, dziękuję Ci. Technicznie rzecz biorąc, to wszystko Twoja wina.

„Zapisanie tego” na papierze doprowadziło do powstania mojego artykułu o tym podejściu dla Martina Fowlera i było moim pierwszym prawdziwym doświadczeniem z procesem redagowania. Martin, dziękuję Ci za cierpliwość wobec mnie i dodatkowe porady, które nadały strukturę temu podejściu w formie tutaj przedstawionej.

Artykuł doprowadził z kolei do kolejnego znaczącego wzmocnienia tego podejścia. Noush Streets, dyrektorka ds. technologii, i jej zespół w firmie Xapo Bank niezwykle szybko zrozumieli jego potencjał i przydatność, ale odmówili pójścia na kompromis w kwestii swojej kultury „zawsze zdalnie i najpierw asynchronicznie”. Zmusiło to mnie i moich kolegów z firmy Thoughtworks do ponownego zastanowienia się, co stanowi istotę tej metody i jak kultura odgrywa jeszcze ważniejszą rolę. Dziękuję wszystkim, z którymi współpracowałem, za nieustępliwość i wymaganie najwyższych standardów w odniesieniu do rezultatów.

Ostatecznym impulsem, który utwierdził mnie w przekonaniu, że to podejście może być powszechnie użyteczne, była sugestia Mathiasa Verraesa i Nicka Tune’a, aby poprosić ponad 800 uczestników konferencji DDD Europe 2022 o ich opinię i ewentualne porady. Rezultatem był materiał The Everybody Keynote. Dziękuję im oraz reszcie zespołu konferencyjnego, a także Gayathri Thiyagarajan i Dianie Montalion za udział, a ponadto Mike’owi Rozinskiemu i Danowi Youngowi za pokierowanie nas ku czemuś niezwykłemu.

W miarę jak książka nabierała kształtu, zdałem sobie sprawę, że jej napisanie będzie wymagało więcej niż tylko godziny dziennie. Dziękuję Patowi Sarnake’owi, Ashokowi Subramanianowi i Shodhanowi Shethowi za sfinansowanie dodatkowego czasu, dzięki któremu mogłem dotrzymać terminów. Dziękuję wszystkim, którzy pracowali ze mną nad projektami, zarówno współpracownikom z firmy Thoughtworks, jak i klientom, oraz tym, którzy dostosowywali się do mojej nieobecności.

W duchu procesu doradztwa poprosiłem o opinie, w miarę jak kolejne rozdziały trafiały do czytelników. Byłem zaskoczony ilością otrzymanych uwag, ale na szczególne wyróżnienie zasługują następujące osoby: Sonya Natanzon, Michael Gray, Dianing Yudono, JD Carlston, Indu Alagarsamy, James Brown, Samit Bico i Romain Vasseur (ze względu na poświęcony czas oraz głębię przemyśleń i wnikliwość, jaką zapewnili). Dziękuję Wam wszystkim, zwłaszcza Sonyi i Michaelowi, którzy dzielili się własnymi doświadczeniami na kolejnych konferencjach. Mam nadzieję, że dostrzeżecie swój wkład na stronach książki.

Miałem również okazję podzielić się swoimi postępami z publicznością podcastów Lead Dev Bookmarked, Happy Path Programming i InfoQ. Dziękuję Suzan Bond, Jamesowi Wardowi, Bruce’owi Eckellowi oraz Thomasowi Bettsowi za zaproszenie mnie i zadbanie o to, by moja wypowiedź była spójna.

Rito Fernando, dziękuję Ci za bycie moją redaktorką prowadzącą. Nauczyłaś mnie, jak pisać. Twoja cierpliwość była fenomenalna, a Twoje notatki po rozmowach były zarówno ratunkiem, jak i czymś niezwykłym. Prawie udało nam się dotrzymać wyznaczonego przez Ciebie ostatecznego terminu. Dziękuję Ci także za to, że byłaś ze mną aż do momentu, gdy odeszłaś do pracy nad czymś o wiele ważniejszym (dziękuję też Corbinowi Collinsowi za interwencję na końcowym etapie).

Melisso Duffield, dziękuję Ci za podjęcie ryzyka związanego z tą książką, która powstała na bazie dość mglistego pomysłu. Louise Corrigan, dziękuję Ci za nadanie kształtu temu pomysłowi i wspieranie mnie na każdym etapie pracy. Obie byłyście współtwórczyniami tego projektu i mam nadzieję, że tak jak ja jesteście dumne z rezultatu.

Clare Laylock, dziękuję Ci za przejęcie pałeczki i podtrzymywanie mojej słabnącej energii podczas pracy nad książką. Shannon Turlington, dziękuję Ci za Twoją cierpliwość i zapewnienie na ostatnich etapach korekty znacznie większej uwagi odnośnie do szczegółów niż ja kiedykolwiek byłbym w stanie uzyskać.

Okazało się, że doświadczenie w postaci pisania książki jest głęboko poruszające na wiele sposobów. Za opiekę nade mną w trakcie wzlotów i upadków (choć być może nie zdawaliście sobie z tego sprawy) dziękuję następującym osobom: Tricia Driver, Valentina Servile, Cat Morris, Amy Lynch, Juke Trabold, Javiera Laso, Krisztina Hirth, Sofia Katsaouni, Aki Salmi, Anne Macedo, Marit van Dijk, Andrea Magnorsky i Kenny Baas-Schwegler.

Na koniec chciałbym podziękować Amandzie, mojej partnerce w rodzicielskich zmaganiach, oraz naszym wspaniałym wspólnym projektom, czyli Charliemu i Hattie. Robiliście mi herbatę, nie pozwalaliście mi myśleć cały czas o książce, zajmowaliście się wszystkim, czego ja nie robiłem, bo pisałem, i co najważniejsze, przypominaliście mi, dlaczego w ogóle się tego podjąłem.

[1] Ma to zastosowanie nawet na najbardziej podstawowym poziomie. Trener rugby mojego syna miał zwyczaj mówić: „Piłka zawsze porusza się szybciej, niż jeden zawodnik może biec”, co oznaczało, że powinni podawać piłkę między sobą, aby zyskać przewagę nad przeciwnikami.

[2] Marc Andreesen, Why Software Is Eating the World, „The Wall Street Journal”, 20 sierpnia 2011; https://www.wsj.com/articles/SB10001424053111903480904576512250915629460.

[3] Nie pomijam celowo innych rodzajów architektów, takich jak architekci bezpieczeństwa lub infrastruktury. Nie oznacza to, że nie znajdziesz w tej książce przydatnych dla siebie fragmentów, ale dynamika Twojego środowiska jest inna.

[4] Jak w stwierdzeniu „dopasowani do zespołu”.

[5] Jeśli jesteś członkiem jednego zespołu i zajmujesz się architekturą, znajdujesz się na dobrej drodze do praktykowania tego, co promuje ta książka. Aby uniknąć łączenia osób z ich rolami, określam to mianem „zespołu projektowego”.

[6] Obecnie nosi nazwę Winter Tech Forum (https://www.wintertechforum.com). To najbardziej niesamowite wydarzenie z udziałem najwspanialszej grupy profesjonalistów z branży oprogramowania, jaką miałem dotąd szczęście spotkać.

Rozdział 1
Praktyki dotyczące scentralizowanej architektury w zdecentralizowanym świecie

„Tradycyjne” podejścia do kwestii architektury oprogramowania stają się coraz bardziej nieskuteczne w obliczu szybko rozwijających się systemów oprogramowania. W tym otwierającym rozdziale opiszę sposób, w jaki te problemy wyniknęły z serii fundamentalnych zmian lub rewolucji, które wymusiły dalszą decentralizację i zwiększyły podatność na informacje zwrotne. Mając na uwadze te rewolucje, przeanalizuję problemy spowodowane przez zależność tradycyjnych metod architektonicznych od przewidywalności i kontroli. Rozdział zakończę wyjaśnieniem, co musi uwzględniać podejście do architektury, skupiając się na tym, jakie mamy możliwości w zakresie planowania, zabezpieczania i reagowania.

Zacznijmy od przedstawienia wartości architektury oprogramowania zarówno od strony praktyki, jak i końcowego rezultatu.

Kluczem do sukcesu jest zarówno praktyka, jak i końcowy rezultat architektury oprogramowania

Czym jest architektura oprogramowania ? Grady Booch definiuje ją w następujący sposób: „Architektura oprogramowania reprezentuje zestaw znaczących decyzji projektowych, które określają kształt i funkcję systemu, w przypadku którego koszt zmiany decyduje o tym, w jaki stopniu coś jest znaczące” [1] . Martin Fowler posługuje się podobną definicją, którą w ramach parafrazy można wyrazić w ten sposób, że architektura oprogramowania reprezentuje decyzje mające zarówno istotne znaczenie, jak i niepozwalające na łatwą zmianę [2] .

Podobają mi się te dwie definicje, ponieważ nie tylko obejmują to, czym jest architektura oprogramowania, ale też podkreślają największą trudność związaną z tym zagadnieniem. Definicja Boocha skłania się ku końcowemu rezultatowi , natomiast definicja Fowlera zmierza bardziej w stronę praktyki . Okazuje się, że termin architektura oprogramowania może odnosić się do jednej lub drugiej definicji albo do obu jednocześnie. Choć powoduje to często niejasności, znaczenia te są zwykle stosowane wymiennie podczas rozmów dotyczących tworzonego oprogramowania. Aby jakikolwiek system oprogramowania odniósł sukces, niezbędny jest zarówno końcowy rezultat, jak i praktyka.

Zestawienie architektury oprogramowania z jej praktyką

W książce będę odróżniał końcowy rezultat od praktyki architektury oprogramowania w następujący sposób:

- Końcowy rezultat, czyli rzeczy, które ostatecznie trafiają do kodu, to „architektura oprogramowania”.

- Decydowanie o tym, co trafi do kodu, to „praktyka architektury oprogramowania”.

Napisano wiele książek na temat końcowego rezultatu architektury oprogramowania, a także o znaczących decyzjach projektowych, które określają kształt i funkcję systemu. Cały czas są projektowane nowe technologie, które wymagają dokonywania zmian w istniejących architekturach lub tworzenia zupełnie nowych. W tym kontekście do gry wchodzą wzorce [3] i architektury referencyjne [4] , które uwzględniają sprawdzone metody budowania systemów.

Można by założyć, że istnieje równie wiele książek dotyczących praktyki architektury oprogramowania. Niestety tak nie jest. Wynika to z tego, że sposób, w jaki praktykuje się architekturę oprogramowania, przez lata zmienił się bardzo niewiele.

Stawka jednak rośnie. Architektura oprogramowania staje się coraz ważniejsza, ponieważ złożoność działających systemów oprogramowania stale się zwiększa. Nasze systemy są większe, częściej ulegają zmianom, są w większym stopniu ze sobą połączone (zarówno z elementami będącymi w naszym posiadaniu, jak i z tymi, nad którymi nie ma kontroli), używane są przez większą liczbę osób przez większość czasu, a ponadto oczekuje się, że nigdy nie zawiodą.

Choć powszechnie uznaje się, że praktyka architektury jest istotna i że należy unikać złej architektury, przez lata innowacje i ulepszenia miały miejsce jedynie w przypadku końcowego rezultatu. Aby w przyszłości osiągnąć sukces, trzeba być otwartym także na ewolucję praktyki architektury oprogramowania.

W książce postarano się poprawić tę nierównowagę. Opisano w niej podejście do praktyki architektury, które pozwala niezawodnie osiągnąć i utrzymać architektoniczne rezultaty końcowe wymagane przez nasze oprogramowanie, a być może nawet poprawić przyszłość projektowania oprogramowania.

Zacznijmy od ustalenia celów dobrej architektury oprogramowania w naszym szybko się zmieniającym i nieprzewidywalnym środowisku technologicznym. Systemy z dobrą architekturą cechują się następującymi rzeczami:

- Ich poszczególne części są spójne, zwarte i zgodne zarówno z domeną, jak i wartością biznesową.

- Ich poszczególne części rozdzielono w odpowiedni sposób, pozwalający wielu niezależnym zespołom zajmować się całym systemem równolegle i razem.

- Częściowo uwzględniają one przyszłą ewolucję, tworząc ogólne architektury wystarczająco dostosowane do zmian.

Biorąc pod uwagę te rzeczy, definicja odpowiedniej praktyki architektury oprogramowania jest trywialna: musi ona dostarczać i utrzymywać te „dobre architektury”.

Gdy właściwie zastosuje się odpowiednie podejścia do praktyki architektury oprogramowania, ich wpływ może być ogromnie pozytywny, o czym sam się przekonałem. Można to dostrzec i odczuć zarówno w procesie wytwarzania oprogramowania, jak i w jego końcowych rezultatach. Tworzenie i uruchamianie kodu staje się efektywne, przewidywalne, łatwiejsze, a nawet przyjemne. Z kolei gdy praktyka architektury oprogramowania jest kiepsko prowadzona, staje się stratą czasu, a ponadto jest nieprzewidywalna i uciążliwa, czyli mówiąc wprost: nie zapewnia zbyt wiele satysfakcji.

Wykorzystajmy te wnioski do analizy aktualnych praktyk architektury oprogramowania, zwłaszcza w kontekście ich skuteczności wobec nowoczesnych architektur (uwaga, spoiler: nie radzą sobie one zbyt dobrze).

Jakie są praktyki w przypadku tradycyjnej architektury?

Jak wspomniałem, standardowe praktyki architektury oprogramowania przez lata nie zmieniły się zbyt mocno. Prawdopodobnie rozpoznasz je od razu, gdy je opiszę. Są one tak wszechobecne, że od teraz będę je nazywał tradycyjnymi . Choć praktyki te obejmują dwie skrajności, które zostaną wkrótce omówione, łączy je jeden wspólny aspekt. Tradycyjne praktyki architektury oprogramowania koncentrują władzę decyzyjną w rękach wybranej grupy osób nazywanych architektami . Ponoszą one odpowiedzialność za wszystkie istotne decyzje architektoniczne.

Zapamiętaj to, gdyż jest to kluczowe z punktu widzenia omówienia zawartego w tym rozdziale.

Pora przejść do dwóch skrajności tradycyjnej praktyki architektury. Dla jasności: w rzeczywistości żaden z tych stereotypów nigdy nie występuje w pełni, ale to, że w naszej branży nadano im nazwy, które wszyscy rozpoznajemy, oznacza, że istnieją one w naszej świadomości.

Architekci z wieży z kości słoniowej

Na jednym końcu znajduje się podejście do praktyki architektury znane jako wieża z kości słoniowej (ang. ivory tower ), które zilustrowano na rysunku 1.1. W ramach tego podejścia wiele zespołów buduje oprogramowanie i stara się płynnie działać. Gdy pojawia się potrzeba podjęcia decyzji architektonicznej, zespoły muszą zwrócić się do architekta, który przebywa w odległej wieży z kości słoniowej.

Rysunek 1.1. Podejście do praktyki architektury znane jako wieża z kości słoniowej

W przypadku tego podejścia próbuje się wywierać wpływ na wszystko związane zarówno z poszczególnymi częściami, jak i z całością, a nawet to kontrolować . Rozumiem przez to, że w ramach tego podejścia czynione są starania, aby wyrażać opinie oraz mieć udział w poszczególnych komponentach oprogramowania zapewniających konkretne opcje, a jednocześnie sprawować nadzór nad tymi wszystkimi elementami prowadzącymi ze sobą interakcję. Aby to osiągnąć, w przypadku praktyk wieży z kości słoniowej analizuje się wszystko z różnych punktów widzenia i perspektyw, a także z uwzględnieniem różnych horyzontów czasowych, nakładając jednocześnie serię ograniczeń, które mają utrzymać wszystko w całości aż do momentu fazy produkcyjnej.

Najbardziej znaczącym problemem praktyk architektonicznych wieży z kości słoniowej jest nadmierne koncentrowanie się na całości kosztem poszczególnych części oraz zespołów starających się je dostarczać i utrzymywać. Jest to konieczne, aby zespoły mogły poradzić sobie z całą zmiennością. Na przykład podejścia wieży z kości słoniowej narzucają wszystkim trzymanie się danego wzorca architektonicznego nawet wtedy, gdy nie pasuje on do konkretnych okoliczności. Dzieje się tak, ponieważ zgodnie z przyjętą logiką taki wzorzec powinien zwiększać przewidywalność różnych rzeczy, a tym samym ułatwiać sprawowanie kontroli.

Architekci oprogramowania stosujący podejście wieży z kości słoniowej są w efekcie postrzegani jako osoby stojące ponad wszystkim, wszechwiedzące i zdolne do ogarnięcia całości sytuacji. Zakłada się, że posiadają oni ogromne doświadczenie, co tradycyjnie wiąże się z ich wyższą pozycją w hierarchii organizacyjnej, co jest kolejnym powodem, dla którego postrzega się ich jako „znajdujących się wysoko”. Tego rodzaju opinie są odzwierciedlone w nazwie identyfikującej to podejście. Termin architekt z wieży z kości słoniowej sugeruje, że jego podejście do architektury jest zbyt oderwane od kodu, by miało jakiekolwiek odniesienie do zwykłej, codziennej rzeczywistości.

Architekci praktyczni

Czy jednak przebywanie „w okopach” na pewno jest równie istotne? Owszem. Ten wariant reprezentuje drugi koniec spektrum praktyk architektonicznych, czyli praktyczne i uwzględniające wiele zespołów podejście do architektury zilustrowane na rysunku 1.2. Ponownie wiele zespołów zajmuje się tworzeniem oprogramowania i stara się utrzymać płynność działań. Lecz gdy pojawia się potrzeba podjęcia decyzji dotyczącej architektury, zespoły muszą zaangażować mobilnego, praktycznego architekta, który spotyka się z nimi w ramach ich własnego kontekstu.

Rysunek 1.2. Praktyczne podejście do architektury angażujące wiele zespołów

Podejście to odzwierciedla istotną determinację architekta do zachowania i potwierdzenia swojej umiejętności tworzenia kodu. W ramach tej praktyki praca architektów odbywa się „od pierwszego wiersza kodu” wśród programistów. Architekci przemieszczają się między zespołami, zadają wszystkie właściwe pytania i zajmują się projektowaniem wspólnie z kierownikami zespołów oraz ze starszymi projektantami. W bezpośrednim kontraście do tego, co jest ważne w przypadku podejścia wieży z kości słoniowej, podejście praktyczne kładzie nacisk na doświadczenia poszczególnych zespołów i szczególnie priorytetowo traktuje kwestię zapewnienia możliwości dostarczenia poszczególnych części rozwiązania.

Podejścia praktyczne wymagają ciągłego przemieszczania się między zespołami w pośpiechu, nigdy nie pozostając w jednym miejscu na tyle długo, by wykonać niezbędną pracę. W efekcie cierpi na tym cały system. Nadmierne skupienie się na pojedynczych zespołach jest słabością tego podejścia, ponieważ „całość” nadal ma ogromne znaczenie, lecz nie jest traktowana jako priorytet. Niezbędne jest podejście, które umożliwi zrównoważenie perspektyw „z bliska” oraz „całościowej”.

Na czym polega problem z obydwoma tradycyjnymi podejściami?

Choć te uogólnienia są celowo polemiczne, oba podejścia zawodzą z tego samego powodu: próbują kontrolować to, czego nie da się kontrolować, oraz przewidywać to, co jest nieprzewidywalne.

Stosowałem zarówno podejście wieży z kości słoniowej, jak i podejście praktyczne. Kierowałem również zespołem projektowym, próbując współpracować z obydwoma typami architektów, dlatego miałem okazję przekonać się, jak różne rzeczy mogą zawodzić na różne sposoby i z wielu perspektyw.

Jako architekt pracujący w wieży z kości słoniowej starałem się utrzymać pod kontrolą zarówno ogólną wizję, jak i szczegóły. Byłem tym, który próbował wyjaśniać znaczenie fundamentalnych wymogów dotyczących bezpieczeństwa informacji i regulacji prawnych (które musiały zostać spełnione z przyziemnych, lecz kluczowych powodów: brak zgodności z różnymi przepisami może poskutkować tym, że firma przestanie istnieć). Z kolei zespoły projektowe były znacznie bardziej podekscytowane nową fajną biblioteką lub podejściem.

Wypełniając obowiązki architekta praktycznego, starałem się w miarę możliwości zaznajomić z całością kontekstu i informacji o domenie. Przemieszczałem się od zespołu do zespołu, zmagając się z koniecznością zmiany kontekstu i usiłując przywołać w pamięci ogromną liczbę szczegółów dotyczących aktualnego celu działań zespołów, ich historii oraz specyfiki ich części domeny biznesowej, a także konkretnych potoków i wymagań środowiska wykonawczego. Jednocześnie słuchałem, co członkowie zespołu mówią na temat dziwnego wzrostu ruchu sieciowego, a przy tym próbowałem zadbać o pewien stopień spójności publicznie udostępnianego, ogólnego interfejsu API.

Z mojego doświadczenia wynika, że wszyscy architekci oprogramowania, bez względu na stosowane w praktyce podejście, są szczerzy, stosując unikalną kombinację tradycyjnych metod (i nie tylko) z jak najlepszymi intencjami. Próbując to robić, starają się jednak osiągnąć pełną kontrolę, ponieważ, niezależnie od wybranego modelu, to oni są odpowiedzialni i rozliczani za całość architektury. Usiłując perfekcyjnie zrównoważyć wszystkie oczekiwania, sami wpędzają się w kłopoty.

W przypadku podejścia wieży z kości słoniowej oznacza to konieczność wprowadzenia komitetów sprawdzających, zatwierdzeń, wydzielonych funkcji związanych z architekturą i ograniczających struktur. A jak to wygląda w alternatywnym podejściu praktycznym? Bliska współpraca w parach, przemieszczanie się między autonomicznymi zespołami oraz podejmowanie prób zrealizowania wszystkich wymaganych prac projektowych wszędzie tam, gdzie są one niezbędne. Żadne z tych podejść nie sprawdza się zbyt dobrze.

Dlaczego tak jest? Wynika to z tego, że z założenia zarówno architekci z wieży z kości słoniowej, jak i architekci praktyczni w najlepszym wypadku są obciążeniem dla zespołów, a w najgorszym prowadzą do złej architektury i kiepskiego oprogramowania.

Jeśli w ramach obu podejść moja praca związana z architekturą zostanie dobrze wykonana, a jej efekty zostaną skutecznie przekazane, mankamentem jest jedynie spowolnienie przeze mnie pracy zespołów, gdyż staję się wąskim gardłem. To najlepszy możliwy rezultat. W sytuacji, gdy zespoły projektowe oczekują coraz szybszego tempa pracy, mogę nieumyślnie blokować ich przepływ pracy, co prowadzi do tego, że czekają bezczynnie na działania z mojej strony.

Często sytuacja wygląda jeszcze gorzej. W miarę jak zespoły stają się coraz bardziej niezależne i z większą częstotliwością mogą wdrażać komponenty w środowisku produkcyjnym, wiedzą o swoich częściach systemu znacznie więcej niż ja kiedykolwiek mógłbym jako architekt. Dokładniej znają swoje wymagania, lepiej rozumieją tworzony przez siebie kod oraz swoją domenę, potoki i środowiska uruchomieniowe, a także swoich klientów. W konsekwencji coraz bardziej polegam na zespołach, które będą mi udostępniały aktualne informacje o stanie wszystkich obszarów, którymi się zajmują. Im częściej muszą to robić, tym bardziej staje się niemożliwe, abym mógł przemyśleć wszystko, co jest wymagane do odgrywania mojej roli — reprezentanta całości składającej się z tych wszystkich niezależnych części.

Nieustannie starałem się dostarczać oprogramowanie spełniające wymagania, zapewniające wartość zarówno użytkownikom, jak i firmie, a jednocześnie zdolne do rozwoju i zmian wraz ze zmieniającymi się potrzebami i technologiami. Próbowałem z całych sił sprawić, by oba tradycyjne podejścia do architektury zadziałały, osobno i razem, lecz nigdy nie udało się to na tyle dobrze, by przestać być osobą blokującą prace lub mieć świadomość każdego niuansu coraz bardziej złożonego systemu.

Żyjemy w świecie, w którym nasze systemy oprogramowania składają się z rosnącej liczby niezależnych, zdecentralizowanych i szybko zmieniających się komponentów, które nie zawsze są w pełni znane ani rozumiane. Przyjrzyjmy się bliżej rodzajom tworzonego obecnie oprogramowania, a także metodom służącym do tego. Dzięki temu stanie się możliwe określenie, jakimi właściwościami musi się cechować odpowiednia praktyka architektury oprogramowania.

Pięć rewolucji, które uwolniły moc oprogramowania

Zmiana jest stałym elementem świata oprogramowania. Zawsze pojawia się nowe narzędzie, język, platforma, technika, podejście, wzorzec, antywzorzec, „właściwa” lub „niewłaściwa” metoda, model organizacyjny albo zmiana wartości, za którą trzeba nadążyć. Pragnienie korzystania z czegoś najnowszego jest tak głęboko zakorzenione w kulturze związanej z oprogramowaniem, że często trzeba przypominać sobie o rzeczywistym celu, czyli dostarczaniu wartościowych i użytecznych rezultatów. Zmiana jest tak ważnym elementem naszego życia, że rozdział 13. poświęcono wyzwaniom, jakie ona ze sobą niesie.

Na przestrzeni lat odpowiedzi na potrzebę i pragnienie wprowadzania zmiany pojawiały się w postaci serii rewolucji, które zmieniły naszą relację z kodem, a w konsekwencji także istniejące architektury oprogramowania. Każda z tych rewolucji kwestionuje kluczowe aspekty ekosystemu tworzenia oprogramowania i oferuje nowy sposób postrzegania otaczającego nas świata oraz jego możliwości (być może nie doświadczasz wszystkich rewolucji lub nawet żadnej z nich, ale możliwość istnieje dla każdego).

Dotychczas miało miejsce pięć rewolucji (przedstawiono je na rysunku 1.3). Nie oznacza to jednak, że nie pojawią się kolejne w przyszłości (już teraz można dostrzec „chmury burzowe” nadciągające w obszarze projektu organizacyjnego, a kto wie, jakie skutki przyniesie technologia uczenia maszynowego).

Rysunek 1.3. Pierwsze pięć rewolucji związanych z oprogramowaniem

Użycie przeze mnie terminu rewolucja do opisania zmian w naszej relacji z kodem i architekturą oprogramowania jest zamierzone. O architekturze oprogramowania można myśleć jak o czymś obracającym się wokół osi, co może całkowicie przewrócić ugruntowany sposób myślenia. Choć obrót może doprowadzić nas z powrotem do punktu wyjścia, spowoduje, że spojrzymy na świat w odmienny sposób.

Pierwsza rewolucja rozpoczęła się wraz z powstaniem Manifestu Agile ( https://agilemanifesto.org/principles.html ). Zachęcał on do ponownego skupienia się na działającym, przetestowanym kodzie [5] oraz na zaufaniu ludziom, którzy go tworzą. Manifest podkreślał siłę technik, takich jak TDD ( Test-Driven Development ), programowanie parami i ciągła integracja, jako sposobu ułatwiającego osiągnięcie tego celu.

Druga rewolucja nadeszła wraz z przetwarzaniem w chmurze. Coraz większa dostępność oraz drastycznie spadające koszty sieci, pamięci masowej i cykli obliczeniowych uświadomiły [6] nam, że nie trzeba posiadać własnych komputerów do uruchamiania naszego kodu. Wystarczy zapłacić komuś za czas korzystania z jego zasobów sprzętowych. Zmieniło to sposób postrzegania tego, jak szybko można przygotowywać i modyfikować używane systemy w środowisku produkcyjnym. Nie trzeba już czekać tygodniami (a nawet miesiącami) na dostawę w opakowaniu nowego serwera, rozpakowanie go, zamontowanie w szafie, podłączenie okablowania i zainstalowanie systemu operacyjnego. Po drugiej rewolucji dokładnie to samo można osiągnąć w ciągu kilku minut po przeprowadzeniu instalacji z poziomu wiersza poleceń [7] . Nasz kod niewiele później może zacząć działać w ramach takiego rozwiązania.

Trzecia rewolucja została zapoczątkowana wraz z metodyką DevOps i ciągłym wdrażaniem. Stało się jasne, że nie ma powodu, by traktować osoby odpowiedzialne za utrzymanie naszych środowisk wykonawczych w chmurze jako część odrębnej kultury, z którą można prowadzić interakcję jedynie za pośrednictwem kolejek ze zgłoszeniami. Zmiana ta, która zburzyła sztuczne granice między rolami w ramach części projektowej (ang. Development ) i operacyjnej (ang. Operations ), zmieniła po prostu sposób, w jaki postrzegano szybkość wdrażania kodu po dostarczeniu go, a także to, kto może ten proces zainicjować. Zespoły operacyjne zaczęły korzystać z narzędzi, które wcześniej były standardem wśród projektantów, aby budować, wdrażać i utrzymywać usługi. W efekcie zespoły dostarczające oprogramowanie mogły samodzielnie obsługiwać całą infrastrukturę oraz potoki, które zautomatyzowały wszystkie kroki realizowane między etapami środowisk produkcyjnego i projektowego. Metodyka DevOps i ciągłe wdrażanie zachęciły nas wszystkich do likwidacji silosów i uzyskania informacji na temat tego, czy nasze systemy działają poprawnie w środowisku produkcyjnym.

Bezpośredni kontakt z systemami działającymi w środowisku produkcyjnym zapoczątkował czwartą rewolucję, wywodzącą się z myślenia produktowego. Ułatwiło nam ono stwierdzenie, że nie ma żadnej gwarancji tego, że rozwiązanie rzeczywiście pasuje do problemu albo że produkt spełnia wymagania rynku, dopóki nie potwierdzą tego użytkownicy. Gdy wydawałem się zbyt pewny efektów swojej pracy, moja koleżanka Monira Rhaimi, która wcześniej była projektantką, a obecnie jest menedżerką produktu, często rzucała mi wyzwanie, pytając: „Skąd jednak wiesz, że rezultaty twojej pracy rzeczywiście działają?”. To zawsze była znakomita uwaga. Dopóki efekty mojej pracy nie zostały wprowadzone i zastosowane w środowisku produkcyjnym, nie mogłem w żaden sposób mieć absolutnej pewności w tej kwestii. Dzięki myśleniu produktowemu nie trzeba już było tworzyć czegoś w płonnej nadziei, że okaże się wartościowe. Obecnie możliwe jest utworzenie tylko takiej ilości kodu, jaka jest konieczna, dostarczenie go i potwierdzenie jego wartości na podstawie opinii użytkowników [8] .

Najnowsza, piąta rewolucja, związana z zespołami skupionymi na strumieniu, uświadomiła nam, że wciąż sami sobie utrudniamy pracę. Nie ma nic bardziej frustrującego niż dwa zespoły o sprzecznych priorytetach i nierównym dostępie do informacji, które dostarczają dwie części jednej opcji w ramach wspólnej bazy kodu. Znacznie lepsze będzie przekazanie wszystkich niezbędnych elementów i informacji jednemu zespołowi i pozwolenie mu na samodzielne działanie. Dzięki temu informacja zwrotna zostanie dodatkowo usprawniona, ponieważ dany zespół ma pełną kontrolę nad obsługą użytkowników od początku do końca i może działać w znacznie bardziej bezpośredni sposób.

Spośród pięciu rewolucji ta miała najdłuższy nieprzerwany okres dojrzewania, być może dlatego, że była ostatnią z nich i czerpała najwięcej z wcześniejszych rewolucji. Już we wczesnym etapie zwróciły na nią uwagę takie osoby jak Eric Evans w książce Domain-Driven Design (Addison-Wesley) oraz Donald Reinertsen w książce The Principles of Product Development Flow (Celeritas). Później James Lewis uczynił ją bardziej praktyczną, formułując wzorzec mikrousług ( https://martinfowler.com/articles/microservices.html ). Jednak dopiero niedawno koncepcja zespołów skupionych na strumieniu zaczęła funkcjonować jako samodzielne podejście w dużej mierze dzięki pracy zespołu DORA Report/Accelerate, książce Marty’ego Cagana Inspired: How to Create Tech Products Customers Love (Wiley) oraz podejściu Team Topologies (topologie zespołowe) opracowanemu przez Matthew Skeltona i Manuela Paisa.

Koncepcja przepływu , do której nawiązuje tytuł książki Reinertsena i która jest również stałym motywem w podejściu Team Topologies, jest bardzo ceniona w świecie produktowym. Odnosi się ona do szybko płynącego „strumienia” wartości bez żadnych przeszkód na jego drodze. Dążenie do osiągnięcia przepływu oznacza ciągłe usuwanie napięć, co sprawia, że informacje zwrotne stają się szybsze i bardziej wartościowe.

W każdej z rewolucji w dziedzinie oprogramowania przewija się idea, że nic nie powinno stać na przeszkodzie w prezentowaniu pomysłu nowej opcji użytkownikom. Dzięki przepływowi taka opcja może szybko przekształcić się w zestaw drobnych historyjek w backlogu zespołu, a następnie w zatwierdzony kod w systemie kontroli kodu źródłowego powodujący zainicjowanie wdrożenia, którego efekty w ciągu kilku minut lub godzin mogą trafić do użytkownika lub zaspokoić jego wymagania (sukces) albo nie (niepowodzenie). W przypadku sukcesu można przejść do kolejnej przyrostowej historyjki użytkownika. Jeśli zostanie poniesiona porażka, analizuje się przyczyny i koryguje tor działań.

Diana Montalion nazywa sumę tych rewolucji „nową fizyką” ( https://www.oreilly.com/live-events/software-architecture-superstream-software-architecture-fundamentals/0636920064981/ ). Jest to idealne określenie. Razem podważają one newtonowskie pewniki w tworzeniu oprogramowania, otwierając przed nami wcześniej niewyobrażalne możliwości. Połączenie tych rewolucji pozwala skrócić miesiące pracy do minut. Domysły i nadzieje można zamienić w eksperymenty, dane i fakty. Możliwość uruchamiania kodu w środowisku produkcyjnym i zbierania informacji zwrotnych jest teraz bardziej dostępna niż kiedykolwiek wcześniej.

Rewolucje nie ułatwiły jednak wszystkiego. Choć przyniosły znaczące, szybkie i prawdopodobnie pozytywne zmiany, jednocześnie postawiły architektów przed wyzwaniem adaptacji i utrzymania spójności systemów.

Wpływ pięciu rewolucji na praktykę architektury

Choć rewolucje w dziedzinie oprogramowania przyniosły nam pożądane zmiany, zwiększyły one również złożoność architektoniczną. Mamy coraz bardziej niezależne i autonomiczne części systemów oprogramowania, które nadal muszą współpracować jako spójna całość. Ponadto odpowiednia logika domenowa (czyli rzeczywiste reguły biznesowe zakodowane w oprogramowaniu) musi należeć wyłącznie i w całości do właściwych zespołów, a one muszą być wystarczająco odseparowane od wszystkich pozostałych. Jednocześnie konieczne jest tworzenie architektury „w sam raz”, aby umożliwić wszystkim częściom systemu zaspokojenie zidentyfikowanych potrzeb oraz elastyczne dostosowywanie się do zmian. Wszystko to musi odbywać się przy równoczesnym uwzględnieniu informacji zwrotnych, które działające systemy dostarczają ze środowiska produkcyjnego.

Nie znając alternatywnych rozwiązań, architekci mogliby sądzić, że muszą polegać na tradycyjnych praktykach architektury. Oznaczałoby to korzystanie z tych samych hierarchii oraz przestrzeganie jednakowych, tradycyjnych schematów, ceremonii, narzędzi i metod interwencji. Problem z tymi tradycyjnymi praktykami polega na tym, że są one zakorzenione w koncepcji władzy i kontroli. Cały arsenał dotychczasowych narzędzi, procesów i technik architektonicznych jest nastawiony na kontrolowanie pewnych aspektów i utrzymywanie tej kontroli w rękach wybranej grupy, aby wszystkim można było zarządzać. Doprowadziło to do konfliktu między tradycyjnymi praktykami architektury i nowoczesnymi architekturami, które stawiają na decentralizację i doceniają zdolność adaptacji.

Poświęćmy czas na właściwe zbadanie wpływu tradycyjnych praktyk na potrzeby nowoczesnych architektur oprogramowania.

Rozkwit decentralizacji

W wyniku rewolucji w dziedzinie oprogramowania nasze architektury systemowe stały się coraz bardziej zdecentralizowane. Decentralizacja umożliwia tworzenie bardziej odpornych i przyszłościowych systemów. Istnieją trzy podstawowe aspekty decentralizacji, które wspierają nasze potrzeby w zakresie nowoczesnego oprogramowania.

Po pierwsze, decentralizacja to nie to samo co dystrybucja . Dystrybucja polega na podzieleniu całości na części, które są następnie rozmieszczane. Gdy robi się to chaotycznie, licząc na poprawę wydajności, można wyrządzić więcej szkody niż pożytku. Mam na myśli sytuacje, w których komponenty są rozdzielane i umieszczane na osobnych serwerach bez uwzględnienia ich wzajemnych powiązań. Załóżmy, że rozdzielany jest monolit z kiepską strukturą mikrousług. Nagle wydajność drastycznie spada, wszędzie pojawiają się przekroczenia limitu czasu, transakcje rozproszone albo trwają wieki, albo są ciągle wycofywane, dane znajdują się prawdopodobnie w nieprzewidywalnym stanie, a wprowadzenie prostej zmiany funkcjonalnej wymaga modyfikacji kilkunastu różnych repozytoriów.

Taka forma dystrybucji jest złym pomysłem, ponieważ elementy, które kiedyś były ze sobą ściśle powiązane, mogłyby zostać rozmieszczone bez sprawdzenia, czy są w stanie funkcjonować oddzielnie. Aby temu zaradzić, można umieścić te części w dwóch różnych wątkach wykonawczych z odrębnymi cyklami istnienia, a ponadto zmusić je do synchronizacji z użyciem zawodnego i wolnego połączenia sieciowego. Niestety to rozwiązanie również nie jest idealne.

Z kolei decentralizacja polega na identyfikowaniu spójnych i kompletnych elementów, które mogłyby działać niezależnie od większej całości. Przykładem tego może być oddzielenie logiki tworzącej zamówienia od logiki realizującej je, co umożliwia utworzenie ich pakietów oraz wdrażanie w postaci oddzielnych mikrousług. Dzięki temu każda z nich może mieć własny cykl istnienia i reagować w sposób odpowiedni tylko dla siebie.

Po drugie, decentralizacja oznacza, że jako architekt lub projektant rezygnujesz ze scentralizowanej kontroli i akceptujesz to, że rzeczy będą musiały być zarządzane w inny sposób. Jeśli rozdzielasz elementy bez oddawania ogólnej kontroli, to nie decentralizujesz, lecz po prostu tworzysz rozwiązanie rozproszone. Wszystko inne niż pełne zaangażowanie w decentralizację utrudni, a nie ułatwi pracę. W rzeczywistości w przypadku dystrybucji lub częściowej decentralizacji musisz być znacznie bardziej świadomy tego, gdzie kontrola jest potrzebna. Dzięki temu możesz się na niej skupić i chronić ją, ale jednocześnie minimalizować, pozwalając na swobodne działanie elementom, które mogą zmieniać się niezależnie.

Weźmy pod uwagę np. języki programowania i wersje środowisk, których zespoły używają przy wdrażaniu podejścia opartego na mikrousługach. Jedną z ich wielkich zalet jest to, że zespoły mogą dokonywać własnych wyborów. Dopóki mikrousługi mogą działać na korporacyjnej platformie chmurowej, wysyłać dzienniki i metryki do środowisk monitorowania, a także nie naruszają żadnych licencji open source , zespoły powinny mieć swobodę wyboru. Oznacza to, że mogą pracować we własnym tempie bez konieczności dostosowywania się do najwolniejszego zespołu, który, mimo najlepszych chęci, utknął na maszynie JVM języka Java 1.4 z powodu zależności od przestarzałego pliku JAR biblioteki Xalan. Zależność ta wynika z faktu, że największy klient nie może zaktualizować swojego starego interfejsu API SOAP, ponieważ jego ostatni projektant odszedł lata temu.

Po trzecie, decentralizacja zwiększy ogólną złożoność systemu. Złożoność nie jest tym samym co skomplikowanie. Ze skomplikowaną sytuacją można sobie poradzić zazwyczaj przez uproszczenie wszystkiego. Złożona sytuacja ma potencjał, by wymknąć się spod kontroli. Taka sytuacja występuje bez intencji kogokolwiek, ponieważ wszystko jest współzależne. Oznacza to zarówno dobre rzeczy (np. efekty sieciowe), jak i te złe (np. kaskadowe awarie systemowe, takie jak podczas załamania kredytowego z 2008 r.).

W świecie z niezwykłą liczbą sieci złożoność rządzi naszymi systemami. Oddaliśmy kontrolę nad tymi częściami systemów, które nie zwiększały przewagi konkurencyjnej (jest to też określane mianem „wymagających dodatków niezapewniających różnicy”). Mowa o centrach danych, systemach zarządzania relacjami z klientami, powiadomieniach w postaci wiadomości SMS, środowiskach sieciowych oraz mechanizmach ciągłej integracji. Dlaczego mielibyśmy tego nie robić? Po co mielibyśmy budować i utrzymywać te rozwiązania samodzielnie, skoro nie zapewniają nam one żadnej unikalnej wartości? Poczucie „kontroli” nie jest wystarczającym uzasadnieniem. Z tego powodu akceptujemy złożoność, aby czerpać z niej korzyści.

Związane są z tym następujące trzy aspekty: w jakim wariancie decentralizacja będzie najbardziej korzystna dla zespołów, kiedy decentralizacja będzie optymalna z punktu widzenia nowoczesnego oprogramowania, a także jak korzyści obu tych aspektów można wykorzystać wtedy, gdy te dwa typy decentralizacji są do siebie dopasowane.

Zespoły działają najlepiej, gdy są zdecentralizowane

Zapytaj dowolnego specjalistę rozwijającego oprogramowanie, czy to początkującego i pełnego zapału, czy doświadczonego i może nieco sceptycznego, a być może opowie Ci o licznych przeszkodach istniejących między jego kodem i środowiskiem produkcyjnym. Kto je tam postawił? Być może wina leży po stronie organizacji i jej struktury kontroli. Może to kwestia zarządzania, a może innego zespołu. Być może chodzi o priorytety albo o współpracownika. A może (wprawdzie rzadko, ale zdarza się to usłyszeć) oni sami są sobie winni.

Niezależnie od źródła tych przeszkód (rzeczywistych lub wyimaginowanych) projektanci mówią tu konkretnie o sprzężeniach, które blokują przepływ. Takie sprzężenia przybierają zwykle jedną z dwóch następujących postaci [9] :

- Sprzężenia w ramach pracy („Czekam, aż oni zrobią swoje rzeczy, abym mógł zrealizować swoje”).

- Sprzężenia związane z uprawnieniami („Czekam na pozwolenie, żeby móc to zrobić”).

Te blokujące powiązania są często pozostałością po scentralizowanych, przedrewolucyjnych podejściach i praktykach. Są one szczególnie szkodliwe, gdy stosuje się je w ramach zdecentralizowanych struktur organizacyjnych i architektur oprogramowania. Dlatego zespoły powinny korzystać z praktyk decentralizacji, które pojawiły się wraz z różnymi rewolucjami. Stosowanie jednego bez drugiego to przepis na porażkę. Jak można to osiągnąć? Odpowiedź kryje się w tych rewolucjach.

Zasady Manifestu Agile ( https://agilemanifesto.org/principles.html ) zachęcają nas np. do „budowania projektów przy wsparciu zmotywowanych osób, a także zapewnienia im niezbędnego środowiska i pomocy oraz zaufania co do tego, że wykonają swoją pracę”. Różne metodyki Agile i Lean wskazują zatem, jak można to zrealizować. Uzupełnieniem tego jest szeroki zakres praktyk DevOps, takich jak dostarczanie ciągłe, które zdecydowanie oddaje kontrolę nad tworzeniem i uruchamianiem oprogramowania z powrotem w ręce jego twórców. Eliminuje to potrzebę koordynowania działań z innymi zespołami oraz konieczność dostosowywania się do tempa narzuconego przez centralnego menedżera wersji lub radę doradczą ds. zmian.

Dzięki zastosowaniu zdecentralizowanych praktyk zespoły odpowiedzialne za tworzenie i obsługę działającego oprogramowania mogą obecnie na własne oczy obserwować, jak ich kod sprawdza się w środowisku produkcyjnym. Myślenie produktowe w połączeniu z tą rzeczywistą informacją zwrotną pozwala nam spojrzeć na oprogramowanie z innej perspektywy, czyli oczami użytkownika. To z kolei umożliwia nam upewnienie się, że wykonana praca faktycznie zapewnia wartość na tyle dużą, że ktoś jest gotowy za nią zapłacić. Jeśli okaże się, że produkt, nad którym pracujemy, nie jest wartościowy, można zmienić kierunek i skupić się na budowaniu rzeczy faktycznie mających wartość.

W zasadzie jesteśmy w stanie dostosować nasze zespoły do profilu biznesowego lub produktu, co jest dokładnie tym, co myśliciele tacy jak Mel Conway [10] i Eric Evans [11] sugerowali już dekady temu. Mój kolega James Lewis ma też ciekawy sposób na wyrażenie tego: „Biznes i jego organizacja powinny być izomorficzne”.

Wykorzystując narzędzia i praktyki wprowadzone przez kolejne rewolucje, stopniowo skracamy czas między napisaniem kodu a momentem uruchomienia go przez użytkownika w środowisku produkcyjnym. W ten sposób systematycznie zwiększa się siłę i rzeczywistą użyteczność kodu. Ponadto, świadomie lub nie, zmierzamy w kierunku niezależnych, zarządzających sobą, samodzielnie organizujących się i samowystarczalnych zespołów wyposażonych we wszystko, co jest im niezbędne do wprowadzania sprawdzonego kodu do środowiska produkcyjnego przy jednoczesnym zapewnianiu wartości i uczeniu się na błędach. Czy nam się to podoba, czy nie, tak właśnie będzie wyglądała przyszłość większości systemów oprogramowania.

Jeśli zostały właściwie zastosowane, wszystkie te nowe narzędzia i praktyki przynoszą ogromne korzyści. Uczestniczyłem w wielu transformacjach cyfrowych, w ramach których rozbijaliśmy silosy tayloryzmu [12] i tworzyliśmy elastyczne granice oparte na segmentacji użytkowników i domenowym obciążeniu poznawczym [13] . Widziałem na własne oczy, jak zmniejszenie stopnia sprzężenia związanego z pracą i uprawnieniami poprawia przepływ i zapewnia najlepsze oprogramowanie w najbardziej efektywny sposób. Takie podejście jest też zrównoważone. Zespoły pracujące w ten sposób są bardziej zadowolone i mniej wypalone [14] .

Nowoczesne oprogramowanie działa najlepiej, gdy jest celowo zdecentralizowane

Aby oprogramowanie spełniało nasze oczekiwania, prawie zawsze musiało być połączone z innymi komponentami, a często z bazą danych za pośrednictwem jakiejś postaci sieci. Gdy oprogramowanie zostało już podłączone do pierwszego zewnętrznego komponentu, wydzielenie kolejnych elementów z różnych powodów nie wydawało się znacznym krokiem. Najpierw umieszczono kod klienta na komputerach stacjonarnych, potem wraz z rozwojem sieci WWW przeniesiono kod interfejsu użytkownika do nowej „warstwy sieciowej”, a następnie całkowicie do przeglądarek. Kroki te jednak nie były jeszcze decentralizacją. Nastąpiła ona, gdy odkryto, że można również korzystać z niezależnych usług zewnętrznych pozwalających uzyskać dodatkową funkcjonalność.

Wraz z korzyściami płynącymi z niezależnych usług zewnętrznych stało się jasne, że decentralizacja wydawała się rozsądnym pomysłem. Dzieląc nasze systemy na małe, autonomiczne części, można było stworzyć systemy potencjalnie mniej podatne na katastrofalne awarie i inne problemy wynikające ze ścisłego sprzężenia. Dzięki minimalizowaniu stopnia koordynacji między różnymi elementami nie wszystko i nie wszyscy muszą być stale zsynchronizowani lub zgodni. Oczywiście tego rodzaju decentralizacja zwiększa złożoność wszystkiego, ale można ją ograniczyć (np. przez umieszczenie kodu różnych usług w oddzielnych repozytoriach). Pozwoliłoby to nam czerpać korzyści z dostępności, odporności, wydajności i skalowalności.

W 2000 r. pracowałem w firmie Sun Microsystems w Linlithgow w Szkocji. Codziennie przechodziłem pod ogromnym szyldem z hasłem „Sieć jest komputerem”. Choć ta wizja była wówczas rewolucyjna dla tego dostawcy, dziś stała się rzeczywistością zarówno dla nas jako konsumentów różnorodnych usług sieciowych, jak i dla profesjonalistów z branży oprogramowania.

W obecnych czasach wszystkie największe i najpotężniejsze systemy oprogramowania używają tych architektur. Nikt już nie zastanawia się dwa razy nad zaprojektowaniem rozwiązania składającego się z różnych, autonomicznych od samego początku podsystemów, które integrują usługi zewnętrzne i udostępniają interfejsy API zespołom spoza naszej organizacji. Z pewnością można korzystać z kolejek komunikatów i wzorców publikowania/subskrypcji, mając pewność, że przy globalnej dystrybucji w wielu wirtualnych centrach danych (w chmurze) odpowiednie elementy pozostają zsynchronizowane, ale tylko w niezbędnym zakresie.

Rozproszone zespoły i ich oprogramowanie muszą działać spójnie

„Bzdura!”. Już słyszę, jak to wykrzykujesz. „Przeszliśmy na ciągłe dostarczanie i to zmieniło życie wszystkich w prawdziwy koszmar! A tematu mikrousług to już nawet nie zaczynajmy…”.

Rozumiem, co masz na myśli. Budowanie zdecentralizowanej architektury to ciężka praca (moje życie polega na pomaganiu klientom w uporaniu się właśnie z tym problemem). Jest to jeszcze trudniejsze, jeśli zespoły nie są zdecentralizowane równolegle z tą architekturą, a wręcz niemożliwe, gdy tradycyjne podejścia nie wspierają praktyki architektury niezbędnej do jej zastosowania jej.

Zdecentralizowane zespoły dostarczają i uruchamiają zdecentralizowane oprogramowanie. Jeśli te dwa aspekty nie są ze sobą spójne, zespoły będą w ciągłym stanie konfliktu, a sprzężenie będzie nadmierne. Może to brzmieć jak truizm, ale z mojego doświadczenia wynika, że takie podejście wcale nie jest powszechne, mimo że wydaje się oczywiste.

W artykule z 1968 r. [15] ( https://www.melconway.com/Home/pdf/committees.pdf ) Conway stwierdził, że ludzkie i organizacyjne aspekty tworzenia oprogramowania mają ogromny wpływ. Jako technolodzy skupiamy się jednak przede wszystkim na oprogramowaniu, licząc na to, że czynnik ludzki sam się ułoży. Niestety my, ludzie, często podświadomie opieramy się zmianom, trzymając się starych, taylorowskich poglądów. Niezależnie od tego, czy jesteś architektem, czy projektantem oprogramowania, książka dostarczy Ci narzędzi ułatwiających współpracę i porozumienie między architektami i zespołami w zakresie praktyk związanych z architekturą oprogramowania.

Zmierzch scentralizowanych praktyk architektury

W punkcie „ Zespoły działają najlepiej, gdy są zdecentralizowane ” wspomniałem, jak zdecentralizowane zespoły zmniejszają stopień sprzężenia, a tym samym mniej się blokują. Innymi słowy: lepiej wykorzystują one dostępne zasoby, takie jak czas. To samo dotyczy architektury oprogramowania. Przyjrzyjmy się odwrotnej sytuacji: nadmiernie scentralizowane architektury oprogramowania są blokujące, a przez to nieefektywne.

Blokowanie, czyli metoda wstrzymywania wykonywania zadania w oczekiwaniu na spełnienie określonego warunku, może objawiać się w systemie oprogramowania na wiele różnorodnych sposobów i w wielu różnych miejscach. (Pamiętasz „sprzężenia powiązane z pracą i uprawnieniami”, o których wspomniałem wcześniej? Jest to odpowiednik architektury oprogramowania). Oto przykłady blokowania:

- Na poziomie sieci podczas oczekiwania na odpowiedzi z punktów końcowych protokołu HTTP.

- Na poziomie bazy danych, gdy blokowane są wiersze (lub co gorsza, jeszcze więcej danych).

- Na poziomie systemu operacyjnego w oczekiwaniu na powrót z wywołania procesu.

- Na poziomie klastra w oczekiwaniu na osiągnięcie kworum lub wybór nowego lidera.

- Na poziomie wdrożenia, gdy efektów Twojej pracy nie umieszczono w pakiecie w postaci niezależnego składnika umożliwiającego wdrożenie, dlatego muszą trafić do środowiska produkcyjnego jako część większej całości, co zmusza do czekania. W takiej sytuacji oczekujesz na zakończenie zautomatyzowanych testów wszystkich zespołów oraz na kolejne okno wdrożenia [16] .

Jako specjaliści odpowiedzialni za utworzenie, uruchomienie i utrzymanie wysokiej jakości produktu musimy dbać o efektywne wykorzystanie środków finansowych. Blokowanie stoi temu na przeszkodzie, ponieważ jest źródłem ogromnego marnotrawstwa. Blokowanie powoduje powstawanie kolejek i sygnalizuje, że podczas gdy niewielka część zasobów być może pracuje naprawdę bardzo intensywnie, wiele innych części systemu może być bezczynnych, czekając na swoją kolej (i potencjalnie przekraczając limit czasu oczekiwania).

Podobnie jak w przypadku decentralizacji, praktyki scentralizowanej architektury mają trzy główne wady: blokowanie przepływu procesu dostarczania, brak uwzględnienia odpowiedniej informacji zwrotnej oraz niezgodność z architekturami zdecentralizowanymi.

Tradycyjne praktyki architektury blokują przepływ procesu dostarczania

Pora skupić się na czynniku ludzkim w tradycyjnych praktykach architektury. Praktyki dotyczące scentralizowanej architektury oprogramowania to główna przyczyna blokowania przepływu procesu dostarczania.

Blokady te pojawiają się jako wąskie gardła wokół architektów i kolejek decyzyjnych, które w konsekwencji tworzą się przed nimi, hamując przepływ pracy. Zaobserwowałem takie blokady w przepływie procesu dostarczania nawet w innowacyjnych firmach i w wysoce efektywnych zespołach, w przypadku których umiejętności techniczne nie budzą wątpliwości. Ostatecznie sprowadza się to do kiepskiego wykorzystania zasobów, wynikającego z niepotrzebnego sprzężenia uprawnień. W tym przypadku jest to oczekiwanie na decyzję architektoniczną lub zatwierdzenie tej, która już została podjęta.

Dlaczego tradycyjne praktyki architektury powodują to blokowanie? Uważam, że dzieje się tak, ponieważ my, technolodzy, chętnie myślimy i działamy kreatywnie wciąż od nowa w imię optymalizacji technicznej, ale rzadko wykorzystujemy te same umiejętności do krytycznego spojrzenia na siebie i na to, jak nasze praktyki mogą prowadzić do sprzężenia na poziomie ludzi. Sporadycznie też wykorzystuje się tę wiedzę, by kwestionować istniejące status quo .

Dlaczego dopiero teraz odczuwamy problemy wynikające ze sprzężeń uprawnień w tradycyjnych praktykach architektury? Wynika to stąd, że tempo procesu dostarczania oprogramowania znacznie wzrosło. Przed pierwszą rewolucją (metodyka Agile) uruchamianie przetestowanego kodu nie było głównym celem, dlatego mieliśmy więcej czasu na przemyślenia. Przed drugą rewolucją (technologia chmury) mieliśmy dość dobre wyobrażenie o platformach uruchomieniowych z wyprzedzeniem miesięcy lub lat, dlatego mogliśmy uwzględnić to w naszych projektach. Przed trzecią rewolucją (metodyka DevOps) wdrożenia były większe i rzadsze, stąd też mogliśmy pracować na większych fragmentach. Przed czwartą rewolucją (produktową) mogliśmy bardziej polegać na zestawie (względnie) statycznych wymagań funkcjonalnych i wielofunkcyjnych. Z kolei przed piątą rewolucją (dostosowanie do strumienia) zespoły były zorganizowane według granic technicznych, a nie domenowych, dlatego w ich przypadku trzeba było rzadziej przełączać się między kontekstami.

Skumulowany efekt dotychczasowych rewolucji w oprogramowaniu sprawia, że coraz więcej zespołów oczekuje częstszego wdrażania większej liczby niezależnych opcji, zapewniając je w środowisku produkcyjnym niemal natychmiast i bez zbędnych przeszkód. Dla nich jest to zupełnie naturalne. To świetna wiadomość dla menedżerów produktu, którzy zawsze chcą, aby użytkownicy jak najszybciej mogli korzystać z oprogramowania. To stopniowe zwiększanie częstotliwości wdrożeń przez coraz większą liczbę niezależnych zespołów oznacza, że praktyka architektury jest potrzebna w wielu miejscach, jednocześnie i wielokrotnie.

Równocześnie tradycyjne praktyki architektury wciąż wymagają, aby wszystkie decyzje przechodziły przez „ucho igielne” architektury, uzyskując obowiązkową „aprobatę odpowiedzialnego architekta”. Choć celem tego podejścia było umożliwienie architektom realizacji trzech głównych założeń dobrej architektury (odpowiednia spójność, właściwe rozdzielenie i wystarczająca możliwość adaptowania), oznacza to, że architekci są przeciążeni. Zilustrowano to na rysunku 1.4.

Rysunek 1.4. Blokujący, szeregowy charakter tradycyjnego podejścia do praktyki architektury zilustrowano tutaj za pomocą stosu dokumentów w skrzynce z prośbami wymagającymi zaangażowania architekta. Symbol zaznaczenia wskazuje zespół, z którym architekt aktualnie współpracuje. Z kolei symbole „zakazu wjazdu” oznaczają zespoły, które również potrzebują wsparcia, ale obecnie czekają na swoją kolej

Oznacza to, że architekci, którzy obecnie są w mniejszości wobec liczby zmian trafiających regularnie do środowiska produkcyjnego, mają dwie możliwości: zrobić jak najmniej i mieć nadzieję, że zespoły programistyczne same zapewnią dobre architektury, albo zrealizować wystarczająco dużo, aby zapewnić spełnienie trzech głównych celów w przypadku każdej zmiany, blokując tym samym przepływ procesu.

Architekci próbujący tworzyć architekturę w tradycyjny sposób są obecnie największą przeszkodą w coraz większej liczbie organizacji, gdyż ich praktyki nie są w stanie poradzić sobie z ilością, różnorodnością i tempem zmian wynikających z pięciu rewolucji, biorąc pod uwagę rozmiar dzisiejszych systemów (a to nawet bez próby nadążania za tempem zmian technologicznych).

Tradycyjne praktyki architektury nie uwzględniają wystarczającej ilości informacji zwrotnych

Blokowanie to pierwszy sposób, w jaki tradycyjne praktyki architektoniczne zawodzą, ale nie jedyny. Równie często nie uwzględniają one wystarczającej ilości informacji zwrotnych dla architektów, którzy z nich korzystają (rysunek 1.5).

Rysunek 1.5. Tradycyjne podejścia związane z praktyką architektury nie uwzględniają wielu informacji zwrotnych pochodzących z działających systemów, takich jak dane o użytkowaniu i wnioski (symbol żarówki) oraz awarie (symbol eksplozji)

Na początku tego rozdziału była mowa o tym, że skrajne praktyki architektury reprezentowane przez wieżę z kości słoniowej nie uwzględniają wystarczającej ilości informacji zwrotnych od zespołów. Praktyki te zawierają niepokojąco mało wbudowanych mechanizmów zbierania opinii, które docierałyby do architektów i wpływały na ich decyzje.

Praktyczne podejścia do kwestii architektury pojawiły się w dużej mierze jako bezpośrednia odpowiedź na ten problem. Słysząc narzekania zespołów projektowych, architekci postanowili zaradzić ich trudnościom. Praktyczne metody obejmują wizyty architektów u zespołów potrzebujących wsparcia, wspólne projektowanie z ich członkami, a być może nawet programowanie w parach przy tworzeniu części szkieletu kodu. Dzięki temu architekci mogą na

własnej skórze przekonać się, jak łatwe lub trudne jest wdrożenie nowej opcji w istniejącej bazie kodu. W konsekwencji uzyskują oni dostęp do informacji zwrotnych wprost z kodu [17] .

To ogromna ilość informacji do pominięcia. W pozostałej części rozdziału wyjaśnię, dlaczego uwzględnianie informacji zwrotnej jest kluczowe , gdy oprogramowanie zdecentralizowane jest tworzone przez rozproszone zespoły.

Tradycyjne praktyki architektury nie pasują do zdecentralizowanego świata

Choć dzięki rewolucjom w dziedzinie oprogramowania możemy szybciej budować lepsze systemy, jednocześnie możliwe jest dostarczanie oprogramowania rozproszonego, które potencjalnie naraża nas na katastrofalne scenariusze awarii. Mogą one być wywołane przez systemy i osoby, o których nie mamy pojęcia, nie mówiąc już o jakiejkolwiek kontroli nad nimi. Architektura oprogramowania często jest źródłem zarówno sukcesu, jak i porażki.

Co więcej, system o odpowiedniej architekturze może być przyjazny w budowie i rozwoju, a ponadto może sam się naprawiać, elastycznie skalować i być niezwykle odporny, co oznacza zdolność do działania nawet w przypadku częściowej awarii. Z kolei system o kiepskiej architekturze może być trudny w utrzymaniu, obciążony długiem technicznym, kosztownie nieefektywny i niezwykle kruchy.

W idealnym świecie architekci praktycy mogliby poświęcać uwagę wszystkim zespołom, zapewniając im indywidualne wsparcie, a jednocześnie mieć na oku architekturę jako całość. W doskonałym świecie podejścia reprezentowane przez architektów z wieży z kości słoniowej uwzględniałyby informacje zwrotne od każdego i o wszystkim. Nie żyjemy jednak w idealnym świecie, a zarówno wariant wieży z kości słoniowej, jak i praktyczne podejścia do architektury mają swoje ograniczenia wynikające z przyjętych metod działania. W zdecentralizowanym systemie oba te rozwiązania wymagają radzenia sobie z wszystkimi niezależnymi i ruchomymi elementami oraz relacjami między zespołami, a także reagowania na częste zmiany dotyczące dosłownie czegokolwiek.

Próba zastosowania scentralizowanych podejść architektonicznych w zdecentralizowanym świecie jest zadaniem niemożliwym do wykonania. Niezbędna jest alternatywa.

Co musi zapewniać każda nowa praktyka architektury?

Niezależnie od podejścia potrzebujemy architektur, które realizują trzy cele dobrej architektury. Muszą one być odpowiednio spójne i zwarte, właściwie rozdzielone oraz wystarczająco elastyczne.

Trzeba wrócić do czystej kartki papieru leżącej na desce kreślarskiej i wyobrazić sobie inne sposoby osiągnięcia tych celów. Dokładniej rzecz biorąc: niezbędny jest zupełnie nowy, uzupełniający system, w którym nasze praktyki architektury współgrają z dynamiką i rytmem zarówno naszych zespołów, jak i systemów oprogramowania, zamiast z nimi rywalizować. Jak już wspomniano, ten nowy system musi mieć dwie kluczowe cechy: musi być zdecentralizowany i przede wszystkim musi uwzględniać informacje zwrotne.

Architektura musi być zdecentralizowana, aby umożliwić niezależnym zespołom podejmowanie dotyczących jej decyzji przy minimalnej koordynacji. Oznacza to, że więcej działań związanych z architekturą może odbywać się równolegle. Dzięki temu można odblokować możliwość tworzenia większej ilości kodu, zoptymalizować przepływ procesu dostarczania i w efekcie uruchomić większą część architektury.

Działająca architektura musi również zapewniać wszystkim bezpośredni i szybki wgląd w jej kształtujące się właściwości. Informacje te muszą być następnie przekazywane bezpośrednio zarówno architektom, jak i zdecentralizowanym, niezależnym zespołom, umożliwiając wszystkim uporanie się ze złożonością, zrozumienie jej i reagowanie na nią w kontekście dalszych decyzji architektonicznych i implementacji [18] .

Aby odnieść prawdziwy sukces, nowe podejście do architektury musi uwzględniać pewne czynniki. Chociaż żadne podejście nie jest w stanie ochronić przed siłami chaosu, powinno ono:

- uwzględniać niepewność,

- zezwalać na emergencję.

Przyjrzyjmy się poszczególnym czynnikom, zaczynając od tego, czego praktyki architektury nigdy nie są w stanie osiągnąć.

Żadne podejście nie ochroni przed siłami chaosu

Żadna praktyka architektury nie jest w stanie ochronić przed chaosem. Używając terminu chaos , mam na myśli jego znaczenie w kontekście fizyki. Według Słownika oksfordzkiego języka angielskiego chaos to „właściwość złożonego systemu, którego zachowanie jest tak nieprzewidywalne, że wydaje się losowe ze względu na dużą wrażliwość na niewielkie zmiany warunków” [19] .

Jestem pewien, że ta definicja chaosu brzmi znajomo dla wielu architektów i projektantów. Ani tworzone przez Ciebie architektury, ani zespoły, które je budują, nie mogłyby zostać opisane jako „przewidywalne”. Być może stwierdzenie „sprawiające wrażenie losowych” wydaje się przesadą, ale założę się, że gdybyś miał wymienić wszystkie czynniki mogące wpłynąć na każdy system bez wyjątku, następnie podjąć się próby wyliczenia potencjalnych konsekwencji ich wszystkich, a potem zastanowić się nad interakcjami wyników tych interakcji, ostatecznie uzyskałbyś ilość informacji znacznie przekraczającą możliwości przetworzenia przez kogokolwiek. A są to tylko te czynniki, o których jesteś w stanie pomyśleć. Rzeczy te są kombinatorycznie złożone. Dodanie choćby jednej nowej rzeczy powoduje lawinowy wzrost liczby powiązań z wszystkimi innymi istniejącymi elementami.

A gdybyśmy zapytali Twojego współpracownika? Czy przypomniałby sobie o kilku relacjach, o których zapomniałeś? Z pewnością tak.

Nie potrzeba wielu niezależnych elementów, żeby stworzyć coś zbyt skomplikowanego do pełnego zrozumienia, nie mówiąc już o przewidywaniu działania tego rozwiązania. Dlatego w ramach każdego nowego podejścia do architektury nie powinno się próbować dokładnie przewidzieć, jak systemy będą funkcjonować, ani zabezpieczać się przed wszystkimi potencjalnymi konsekwencjami.

Architektury powinny uwzględniać niepewność

Architektura zdecentralizowana będąca kombinacją pozornie prostych elementów, takich jak niezależne zespoły i ich autonomiczne moduły oprogramowania, prowadzi do pojawienia się niepewności. Skąd ona się bierze? Wynika ze zmienności. Zmienność , którą bardziej szczegółowo omówię w rozdziale 13., odnosi się do niewiadomych w procesie tworzenia oprogramowania, które wymagają uwagi. Są to niewiadome obecne przez cały cykl ewolucji systemu.

Pomyśl o tym: dysponujesz systemem składającym się z wielu współdziałających komponentów. Są to nie tylko komponenty tworzonego oprogramowania, ale także budujące je zespoły, narzędzia używane do wdrażania, procesy umożliwiające współpracę podczas tworzenia i uruchamiania systemu, infrastruktura, w obrębie której jest on budowany i aktywowany, a  także zewnętrzne zależności, na których bazuje oprogramowanie. Wszystko to stanowi istotne części tego, co powszechnie określa się mianem systemu socjotechnicznego zaangażowanego w tworzenie i obsługę oprogramowania.

Co to jest system socjotechniczny?

System socjotechniczny to koncepcja reprezentująca interakcję między aspektami społecznymi i technologicznymi w środowisku pracy. Pojęcie to zostało pierwotnie sformułowane przez Erica Trista, Kena Bamfortha i Freda Emery’ego podczas II wojny światowej na podstawie ich badań nad angielskimi górnikami pracującymi w kopalniach węgla.

Obecnie wraz z rozwojem technologii fundacja Interaction Design Foundation definiuje system socjotechniczny ( https://www.interaction-design.org/literature/topics/socio-technical-systems ) jako „taki, który uwzględnia wymagania obejmujące aspekty sprzętowe, programowe, ludzkie i społecznościowe. Podejście to obejmuje zrozumienie struktur społecznych, ról i praw (nauki społeczne) w celu zapewnienia informacji na potrzeby projektu systemów angażujących społeczności ludzi i technologię”.

Jeśli nawet rozpatruje się go osobno, każdy element nie jest ani w pełni zrozumiały, ani przewidywalny. Każdy z nich może być źródłem zmienności. W połączeniu stają się one jeszcze bardziej skomplikowane, ponieważ gdy wchodzisz w interakcję z czymś, wówczas nie tylko na to oddziałujesz, ale również to oddziałuje na Ciebie. Jest to dwukierunkowe działanie, które zmienia obie strony.

Być może nawet myślisz sobie teraz: „Jeśli jednak dysponuję dwoma komponentami, z których jeden wywołuje drugi, mogę przewidzieć wyniki tej operacji w głowie”. W tym momencie muszę zwrócić uwagę na najważniejszą koncepcję, która jest źródłem złożoności systemów.

Rozważmy prosty, hipotetyczny scenariusz interakcji między elementami A i B. W tym ujęciu stwierdzenie, że „element A powoduje jakieś zdarzenia dotyczące elementu B”, to przykład myślenia liniowego . W rzeczywistości jednak będące tego konsekwencją działania elementu B sprawią, że również w przypadku elementu A coś się wydarzy .

Wyobraźmy sobie rozważanie wyłącznie technicznego systemu, czyli synchronicznej interakcji, takiej jak żądanie GET protokołu HTTP. Po wysłaniu żądania element A czeka na odpowiedź elementu B. Jeśli dysponuje on tym, czego wymaga element A, otrzyma to prawdopodobnie w postaci komunikatu odpowiedzi 200 OK wraz z ładunkiem danych. W przeciwnym razie element A będzie musiał też zareagować na takie ewentualne komunikaty jak 404 (nie znaleziono), 500 (błąd wewnętrzny serwera) itp.

Nawet w tym scenariuszu „normalnego działania” widać, że ma miejsce kilka rzeczy. Wystarczy dodać tylko kilka innych możliwości, aby sytuacja stała się bardziej skomplikowana. Co będzie, jeśli element B potrzebuje dużo czasu na odpowiedź, a zanim to nastąpi, element A ponowi próbę? W tym przypadku element B (potencjalnie) dwukrotnie wykona operację na potrzeby elementu A. Czy powinien on zapewnić elementowi A dwie rzeczy, których tamten zażądał? A może powinien przekazać elementowi A tę samą rzecz dwa razy?

Być może, zamiast ponownej próby, element A przestaje czekać i szuka innego sposobu na osiągnięcie swojego celu. Oznacza to, że gdy element B w końcu zwraca dane elementowi A, nie jest on już dostępny, aby cokolwiek z nimi zrobić. Co wtedy robi element B? Czy w ogóle się tym przejmuje? Czy zwalnia jakieś zasoby? Czy w ogóle wie, że element A nie jest już zainteresowany?

Zadając te pytania, otwieramy nasz skomplikowany, sztuczny, czysto technologiczny świat na otaczającą nas rzeczywistość społeczno-techniczną. Dlaczego element B potrzebował wiele czasu na odpowiedź? Czy dlatego, że był już obciążony innymi żądaniami? Podobnie: dlaczego element A przestał czekać? Czy dlatego, że jego wymagania zostały spełnione gdzie indziej? A może po prostu się znudził? Jak widać, nawet ten niezwykle prosty przykład daje wiele do myślenia, gdy ma się do czynienia z interakcjami, a nasze systemy nigdy nie są tak proste.

To jeszcze nie wszystko. Gdy do całości tego obrazu doda się kolejne dobrze znane komponenty, każdy z nich może wchodzić w interakcje ze wszystkimi pozostałymi na niezliczone sposoby, i to niekoniecznie bezpośrednio. Oto ciekawe ćwiczenie do wypróbowania: wprowadź pewne opóźnienie do pojedynczej części dowolnego systemu, który obecnie obsługujesz. Nie ma znaczenia, czy ta część jest trywialna, czy znajduje się na peryferiach. Sprawdź, co się stanie. Możesz być zaskoczony tym, jak zwykłe spowolnienie jednej rzeczy może popsuć pozornie niezwiązane elementy [20] .

Każde nowe podejście do architektury musi potwierdzać, a nawet uwzględniać informacje z jak największej liczby interakcji między komponentami, aby móc reagować na zmienne i nieprzewidywalne sytuacje, które nieuchronnie się pojawiają.

Architektury powinny dopuszczać emergencję

Co może być bardziej zaskakujące niż odkrycie w systemie oprogramowania właściwości, których nie zaprojektowałeś? Mogą to być właściwości, które nie pochodzą z pojedynczej części, lecz powstały w wyniku interakcji wielu części.