Dane oryginału
Original edition copyright © 2017 by The Pragmatic Programmers, LLC. All rights reserved. Title of English-language original: Design It! From Programmer to Software Architect by Michael Keeling, ISBN 978-1-68050-209-1. Polish-language edition © 2019 by Polish Scientific Publishers PWN Wydawnictwo Naukowe PWN Spółka Akcyjna. All Rights reserved.

Przekład

Przekład Mariusz Rogulski, Magdalena Rogulska na zlecenie WITKOM Witold Sikorski

Projekt okładki polskiego wydania

Joanna Andryjowicz

Wydawca

Wioleta Szczygielska-Dybciak

Redaktor prowadzący

Jolanta Kowalczuk

Redaktor

Mariusz Dobkowski

Koordynator produkcji

Anna Bączkowska

Konsultant merytoryczny

Przemysław Bykowski

Skład wersji elektronicznej na zlecenie Wydawnictwa Naukowego PWN

Anna Jakubowska / Woblink

Zastrzeżonych nazw firm i produktów użyto w książce wyłącznie w celu identyfikacji.

Copyright © by Wydawnictwo Naukowe PWN SA

Warszawa 2019

ISBN 978-83-01-20856-1

eBook został przygotowany na podstawie wydania papierowego z 2019 r., (wyd. I)

Warszawa 2019

Wydawnictwo Naukowe PWN SA

02-460 Warszawa, ul. Gottlieba Daimlera 2

tel. 22 69 54 321, faks 22 69 54 288

infolinia 801 33 33 88

e-mail: pwn@pwn.com.pl; reklama@pwn.pl

www.pwn.pl

Spis treści

Podziękowania

Przedmowa

Witamy

Część I
Wprowadzenie do architektury oprogramowania

1. Zostać architektem oprogramowania

Czym zajmują się architekci oprogramowania?

Czym jest architektura oprogramowania?

Zostańmy architektami w naszym zespole

Budowanie niesamowitego oprogramowania

Studium przypadku: Projekt Lionheart

Co dalej

2. Podstawy myślenia projektowego

Cztery zasady myślenia projektowego

Zastosowanie nastawienia projektowego

Myślenie, robienie, sprawdzanie

Co dalej

Część II
Podstawy projektowania architektury

3. Opracowywanie strategii projektowania

Poszukiwanie satysfakcjonującego projektu

Decydowanie, ile zaprojektować na początku

Niech ryzyko będzie naszym przewodnikiem

Tworzenie planu projektowania

Projekt Lionheart: do tej pory…

Co dalej

4. Wczuwanie się w interesariuszy

Rozmawianie z właściwymi ludźmi

Tworzenie mapy interesariuszy

Odkrywanie celów biznesowych

Projekt Lionheart: do tej pory…

Co dalej

5. W poszukiwaniu wymagań istotnych dla architektury

Zawężanie możliwości projektowych za pomocą ograniczeń

Definiowanie atrybutów jakościowych

Poszukiwanie klas wymagań funkcjonalnych

Dowiedzmy się, co jeszcze wpływa na architekturę

Poszukiwanie potrzebnych informacji

Budowanie specyfikacji ASR

Projekt Lionheart: do tej pory…

Co dalej

6. Wybór architektury (zanim ona wybierze nas)

Rozszerzamy, aby dostrzegać możliwości, zawężamy, aby decydować

Akceptowanie ograniczeń

Wspieranie pożądanych atrybutów jakościowych

Przypisywanie elementom funkcjonalnych obowiązków

Projektowanie z myślą o zmianach

Projekt Lionheart: do tej pory…

Co dalej

7. Tworzenie fundamentów z użyciem wzorców

Czym jest wzorzec architektoniczny?

Wzorzec warstwowy

Wzorzec porty i adaptery

Wzorzec potoki i filtry

Wzorzec architektury zorientowanej na usługi

Wzorzec publish-subscribe

Wzorzec współdzielonych danych

Wzorzec wielowarstwowy

Wzorzec centrum kompetencji

Wzorzec otwartego udziału

Wzorzec wielkiej kuli błota

Odkrywanie nowych wzorców

Projekt Lionheart: do tej pory…

Co dalej

8. Zarządzanie złożonością za pomocą sensownych modeli

Myślenie o architekturze

Projektowanie metamodelu

Wbudowywanie modeli do kodu

Projekt Lionheart: do tej pory…

Co dalej

9. Prowadzenie architektonicznych warsztatów projektowych

Planowanie architektonicznych warsztatów projektowych

Wybieranie odpowiednich działań projektowych

Zapraszanie właściwych uczestników

Zarządzanie grupą

Praca z rozproszonymi zespołami

Projekt Lionheart: do tej pory…

Co dalej

10. Wizualizacja decyzji projektowych

Przedstawianie architektury z różnych perspektyw

Rysowanie fantastycznych diagramów

Projekt Lionheart: do tej pory…

Co dalej

11. Opisywanie architektury

Opowiadanie całej historii

Dopasowywanie metody opisu do sytuacji

Szanowanie swoich odbiorców

Tworzenie widoków wokół potrzeb interesariuszy

Wyjaśnianie powodów naszych decyzji

Projekt Lionheart: do tej pory…

Co dalej

12. Karty oceny dla architektury

Ocenianie służy uczeniu się

Testowanie projektu

Prowadzenie warsztatów ewaluacyjnych

Oceniajmy wcześnie, oceniajmy często, oceniajmy w sposób ciągły

Projekt Lionheart: do tej pory…

Co dalej

13. Wzmacnianie architektów w zespole

Promowanie myślenia architektonicznego

Ułatwianie podejmowania decyzji i wspieranie rozwoju umiejętności

Stworzenie możliwości bezpiecznej praktyki

Delegowanie kompetencji projektowych

Wspólne projektowanie architektury

Projekt Lionheart: epickie podsumowanie

Co dalej

Część III
Skrzynka narzędziowa architekta

14. Działania na rzecz zrozumienia problemu

Działanie 1. Wybór jednej rzeczy

Działanie 2. Mapa empatii

Działanie 3. Warsztaty cel-pytanie-metryka

Działanie 4. Wywiad z interesariuszami

Działanie 5. Lista założeń

Działanie 6. Sieć atrybutów jakościowych

Działanie 7. Miniwarsztaty atrybutów jakościowych

Działanie 8. Mad lib „punkty widzenia”

Działanie 9. Miara odpowiedzi sofizmatu rozszerzenia

Działanie 10. Mapa interesariuszy

15. Działania w celu zbadania potencjalnych rozwiązań

Działanie 11. Personifikacja architektury

Działanie 12. Architektoniczny flipbook

Działanie 13. Karty komponent-odpowiedzialność-współpracownik

Działanie 14. Mapa pojęć

Działanie 15. Dzielenie i zdobywanie

Działanie 16. Burza zdarzeń

Działanie 17. Grupowe postery

Działanie 18. Projektowanie karuzelowe

Działanie 19. Wspólna sesja przy białej tablicy

16. Działania służące osiągnięciu namacalności projektu

Działanie 20. Zapisy decyzji architektonicznych

Działanie 21. Architektoniczne haiku

Działanie 22. Diagram kontekstowy

Działanie 23. Lista najpopularniejszych haseł

Działanie 24. Tablica koncepcyjna

Działanie 25. Modularny diagram dekompozycji

Działanie 26. Odrzucone ścieżki

Działanie 27. Prototypowanie w celu zdobycia wiedzy lub podjęcia decyzji

Działanie 28. Diagram sekwencji

Działanie 29. Metafora systemowa

17. Działania służące ocenie możliwości projektowych

Działanie 30. Briefing architektury

Działanie 31. Przegląd kodu

Działanie 32. Macierz decyzyjna

Działanie 33. Obserwacja zachowania

Działanie 34. Pytanie-komentarz-potrzeba

Działanie 35. Burza ryzyk

Działanie 36. Sprawdzanie poczytalności

Działanie 37. Przegląd scenariusza

Działanie 38. Szkicowanie i porównywanie

D1. Biografie przedstawicieli społeczności

Bibliografia

Przypisy

Podziękowania

Najbardziej pamiętnym momentem w trakcie pisania książki był ten, kiedy moja żona i pięcioletni syn pomagali mi znaleźć sposób na uporządkowanie rozdziałów 1 i 2. Pewnego sobotniego ranka Marie zadawała pytania i słuchała moich wyjaśnień, podczas gdy Owen, z długopisem w ręce, przez ponad godzinę pomagał mi zapisywać pomysły na karteczkach samoprzylepnych i przyklejać wokół kuchennego okna. Oboje jesteście niesamowici. Dziękuję za Waszą miłość i cierpliwość.

Nieprzekraczalne terminy rzeczywiście mijają jak z bicza strzelił. Najlepszym nieprzekraczalnym terminem i jedynym, którego nie przegapiłem podczas pisania tej książki, był Finn. Witaj na świecie!

Mamo, tato, Ryan – ta książka była możliwa tylko dzięki Waszemu wsparciu i zachętom przez całe moje życie. Chris i Russ, dziękuję za pomoc w znalezieniu czasu na pisanie (i za lasagne). Lela, dzięki za słuchanie.

Miałem szczęście czerpać wiedzę od wielu inteligentnych architektów i projektantów oprogramowania, którzy bardzo mnie zainspirowali, współpracować i spotykać się z nimi. Należą do nich m.in.: David Garlan, Mary Shaw, George Fairbanks, Len Bass, Rebecca Wirfs-Brock, Simona Brown, Ariadna Fonta, Matt Bass, Toni Lattanze, Dave Root i Ipek Ozkaya.

Miałem armię technicznych recenzentów, którzy dzięki swoim precyzyjnym uwagom poprawili tę książkę. Byli nimi: David Bock, Will Chaparro, Javier Collado, Fabrizio Cucci, George Fairbanks, Kevin Gisi, Thijmen de Gooljer, Rod Hilton, Michael Hunter, Maurice Kelly, Joe Kramer, Nick McGinness, Ryan Moore, David Morgan, Emanuele Origgi, Ipek Ozkaya, Will Price, Antonio Gomes Rodrigues, Jesse Rosalia, Tibor Simic, Stephen Wolff, Eoin Woods, Peter WA Wood i Colin Yates. Dziękuję wszystkim w IBM Pittsburgh za to, że chcieli być królikami doświadczalnymi wielu metod projektowania.

Susannah Pfalzer, najbardziej niesamowitej redaktorce dla początkującego autora, dziękuję za poprowadzenie mnie przez proces pisania i publikowania. Andy i Dave, dziękuję za danie mi szansy na udoskonalenie sposobu, w jaki budujemy oprogramowanie.

Przedmowa

Kiedy przygotowywałem ostateczny szkic tej książki, początkowo byłem zaskoczony tym, że nie było w nim żadnej wzmianki o programowaniu zwinnym (ang. agile software development). Michael i ja od lat rozmawialiśmy o tej książce i myślałem, że wiem, o czym ona ma być i dlaczego należało ją napisać: idee architektury oprogramowania, zgodnie z tradycją, były trudne do wykorzystania w procesach Agile, ale Michael znalazł sposób, jak je zastosować. Dlaczego zatem Agile nie miałoby być na każdej stronie książki?

Michael jest współczesnym Prometeuszem, zafascynowanym technologią i zdeterminowanym, by ją oswoić dla całej ludzkości. Głęboko wierzy w korzyści płynące z Agile i jest ekspertem w architekturze oprogramowania. Nie znam nikogo, kto w ciągu dnia wcielałby się w rolę przywódcy zespołu Agile, a w nocy był mentorem dla studentów architektury oprogramowania Carnegie Mellon. Znam go najlepiej dzięki naszemu zaangażowaniu w konferencję SATURN poświęconą architekturze oprogramowania, na którą wniósł idee i przyprowadził przywódców społeczności Agile, z którymi się koleguje w społeczności architektów. Szukał najlepszego z obu światów, mieszanki Agile i architektury niebędącej olejem i wodą.

Były inne próby pogodzenia różnic, ale wszystkie były ograniczone. Na początku próbowano na siłę zastosować Agile w fazie implementacji modelu kaskadowego. Inni bez zastrzeżeń zakładali, że nadal istnieje „najważniejszy architekt” podejmujący najistotniejsze decyzje. Prawie wszystkie opierały się na teorii, a nie na raportach z tego, co zostało z powodzeniem zastosowane, i były pisane przez autora jednego z obozów próbującego wyciągnąć pomysły od tych z drugiego.

Ta książka jest inną, lepszą syntezą Agile i architektury, dlatego słowo „Agile” nie występuje na każdej stronie. Zaczyna się od dogłębnego przedstawienia i docenienia wartości Agile, a następnie opisu kompatybilnych technik projektowania. Michael samodzielnie wymyślił lub zaadaptował wiele technik, ale ekscytuje mnie też to, że wybrał najlepsze pomysły z konferencji z ostatnich kilku lat, nieopisywanych jeszcze w żadnej innej książce. Jeśli rzucimy okiem na część III: Narzędzia architekta, to nie zobaczymy „Wyrytych przez architekta kamiennych tablic z przykazaniami dla zespołu”. Zobaczymy działania, które będą pasować nawet dla tygodniowych iteracji, zachęcających do współtworzenia projektu przez zespół i promujących projektowanie jako priorytetowe zadanie zespołu. Ta część zawiera również przedstawienie zespołów faktycznie stosujących te techniki.

Ci sami liderzy merytoryczni, którzy obalali biurokratyczne procesy tworzenia oprogramowania, ostrzegali nas również, że Agile nie jest kamuflażem dla niezdyscyplinowanego kodowania na zasadzie wolnej amerykanki. Te biurokratyczne procesy sprzed epoki Agile w większości przypadków opierały się na zasadach i wiadomo było, jakie działania projektowe należy wykonywać i kiedy. Mimo że zespoły raportują, iż postępują zgodnie z Agile, z mojego doświadczenia wynika, że niezdyscyplinowane kodowanie zdarza się często.

Skoro ta książka już istnieje, pytanie brzmi: co dalej? Trudno jest to określić, szczególnie odnośnie do tego, co będzie w przyszłości, ale moje przewidywania są następujące. Jesteśmy na progu przejścia do stanu stabilnego rozwoju oprogramowania, w którym nauczyliśmy się mieszać zwinność i dyscyplinę. Nasze procesy będą wykorzystywać pętle szybkiego sprzężenia zwrotnego spopularyzowane przez Agile i poprowadzą nas do projektowania technologii napędzających jakość. Niewątpliwie chodzi tu o procesy, w których będzie się wdrażać działania oraz techniki szczególnie odpowiednie do tworzenia oprogramowania.

Jeszcze nie doszliśmy do tego etapu, ale ta książka wskazuje nam odpowiedni kierunek. Zbudujmy przyszłość, w której chcemy żyć.

George Fairbanks
Autor Just Enough Software Architecture

Witamy

Architektura oprogramowania to fundament, na którym jest budowane doskonałe oprogramowanie. Sama świetna architektura nie wystarczy, aby zagwarantować, że oprogramowanie będzie sukcesem, ale zła architektura niemal gwarantuje porażkę. Architektura oprogramowania jest tak ważna, że każdy programista powinien wiedzieć, jak ją zaprojektować.

Z tej książki dowiemy się, jak projektować znakomite architektury oprogramowania. Żeby było jasne, to nie jest lekcja abstrakcyjnego projektowania oprogramowania w wieży z kości słoniowej. Nie znajdują się tu też żadne magiczne rozwiązania – frameworki i technologie, które w cudowny sposób rozwiązują każdy problem. Dowiemy się, jak zastosować podstawowe zasady oraz praktyki projektowania, które uczynią nas lepszymi programistami, architektami i liderami technologicznymi.

Projektowanie dobrego oprogramowania wymaga czegoś więcej niż opanowania zasad i praktyk. Sposób projektowania systemu oprogramowania jest tak samo ważny jak końcowy rezultat. Z tej książki dowiemy się, jak używać myślenia projektowego i metod skoncentrowanych na człowieku, aby projektować architekturę oprogramowania we współpracy ze swoim zespołem. Takie podejście pomaga budować silniejszy związek między podejmowanymi decyzjami projektowymi a ludźmi, których dotyczą te decyzje. Umieszczanie ludzi na pierwszym miejscu pozwoli podejmować lepsze decyzje, a w rezultacie tworzyć lepsze oprogramowanie.

Kto powinien przeczytać tę książkę?

Ta książka jest dla każdego, kto kiedykolwiek stanął przy białej tablicy i szkicował pudełka oraz linie, starając się odpowiedzieć na trudne pytania.

Jeśli projektowanie architektury oprogramowania to dla was całkowita nowość, ta książka jest doskonałym wprowadzeniem. Zaczniemy od podstaw i przejdziemy przez elementarne zasady, które należy znać, aby móc stać się niesamowitymi architektami oprogramowania.

Jeśli jesteście programistami, którzy już coś wiedzą na temat architektury, ta książka pomoże wam uporządkować myśli. Podczas lektury znajdziecie koncepcje, które intuicyjnie wyczuwaliście, ale nie mieliście dla nich nazwy, a także znajdziecie luki, o których nawet nie wiedzieliście, że zostały ominięte. Po przeczytaniu tej książki będziecie w stanie wyjaśnić, dlaczego robicie to, co robicie, co pozwoli wam lepiej przewodzić innym.

Jeśli jesteście już architektami oprogramowania i nie jest to wasze pierwsze rodeo, ta książka da wam świeże spojrzenie na to, jak poprowadzić swój zespół. Młodsi programiści w dzisiejszych czasach oczekują, że będą mogli mieć większy wpływ na rozwiązanie programistyczne systemu, które tworzą. Nacisk na podstawy w tej książce przygotuje was do nauczania dzisiejszych programistów – architektów jutra i bycia ich mentorami, aby mogli w pełni uczestniczyć w procesie projektowania. Wspólne metody projektowania opisane w tej książce dadzą nowe techniki bezpiecznej i produktywnej współpracy z mniej doświadczonymi członkami zespołu podczas wspólnego projektowania systemu oprogramowania.

Jak czytać tę książkę

Książka jest podzielona na trzy części. Części I i II są przeznaczone do przeczytania od początku do końca. Część III została zaprojektowana tak, aby łatwo znajdować odwołania.

W części I poznamy podstawy architektury oprogramowania i myślenia projektowego potrzebne, aby stać się architektami.

W części II nabędziemy podstawowe umiejętności i wiedzę, którą powinni posiadać wszyscy architekci oprogramowania.

Część III zawiera zestaw praktycznych metod projektowania architektury. Nie ma cudownych rozwiązań, ale każdy inżynier oprogramowania ma swoją skrzynkę narzędziową wypełnioną praktykami, metodami i technikami, które razem umożliwiają tworzenie zadziwiającego oprogramowania. Metody w części III pochodzą z mojego zestawu narzędziowego i będę miał zaszczyt podzielić się nimi z wami.

Każdy rozdział w częściach II i III koncentruje się na innym sposobie myślenia o projekcie, o czym dowiemy się więcej w rozdziale 2: Podstawy myślenia projektowego na stronie 17. Podstawy w projektowaniu to sposoby myślenia o świecie, które pomagają nam skupić naszą uwagę na właściwych szczegółach we właściwym czasie. Istnieją cztery nastawienia projektowe (ang. design mindsets): rozumienie, badanie, tworzenie i ocenianie. Poszukajcie ikony na początku każdego rozdziału, aby dowiedzieć się, o którym nastawieniu będziemy się uczyć.

Porady i wskazówki od społeczności

Otwierając tę książkę, przystąpiliście do społeczności architektów oprogramowania, którzy pomagają sobie wzajemnie, dzieląc się radami, wskazówkami i dobrymi praktykami. Aby oficjalnie powitać nas w społeczności, poprosiłem innych architektów oprogramowania, żeby przekazali wskazówki i porady, które ich zdaniem należy znać. Znajdują się one w wyróżnionych ramkach w całej książce.

Naszymi wyjątkowymi przedstawicielami tej społeczności są Len Bass, Bett Bollhoefer, Simon Brown, George Fairbanks, Thijmen de Gooljer, Patrick Kua i Ipek Ozkaya. Więcej informacji na ich temat znajduje się w części Dodatek 1, Biografie przedstawicieli społeczności na stronie 331.

Studium przypadku

Mówiąc o abstrakcyjnych rzeczach, bardzo łatwo pozostać abstrakcyjnym. Aby temu zapobiec, dodałem studium przypadku – Projekt Lionheart – oparty na rzeczywistych systemach, nad którymi pracowałem w przeszłości. Studium przypadku zostało przedstawione w rozdziale 1. Przykłady z tego studium będą znajdowały się w kolejnych rozdziałach książki.

A teraz do dzieła – ćwiczenia

Świetni architekci oprogramowania wykonują ciężką pracę. Aby zostać świetnymi architektami oprogramowania, musimy ćwiczyć projektowanie, a nie tylko o nim mówić. Za każdym razem, gdy zostanie umieszczona ta ikona, to będzie czas, aby pomyśleć krytycznie i wprowadzić teorię do praktyki. Jak projektowanie architektury w prawdziwym świecie, tak ćwiczenia A teraz do dzieła mają wiele właściwych odpowiedzi. Sposób dotarcia do odpowiedzi – podróż do niej – jest tak samo ważna jak samo rozwiązanie.

Zasoby online

Ta książka ma własną stronę internetową[1], można tam znaleźć szczegółowe informacje na jej temat, zamieszczać posty na forach dyskusyjnych i zgłaszać błędy, takie jak literówki, i sugestie dotyczące treści. Fora dyskusyjne to idealne miejsce, aby porozmawiać z innymi czytelnikami i podzielić się rozwiązaniami do ćwiczeń.

Witam, dziękuję za przyłączenie się do mnie, zaczynamy!

Część I

Wprowadzenie do architektury oprogramowania

Zanim będziemy mogli zanurzyć się w temacie, musimy omówić kilka elementarnych pojęć. Obejmują one zarówno podstawowe zasady architektoniczne, jak i fundamenty projektowania.

ROZDZIAŁ 1

Zostać architektem oprogramowania

Nie jestem do końca pewien, kiedy zostałem architektem oprogramowania. Pamiętam, kiedy pierwszy raz ktoś mnie tak nazwał. Byliśmy na ważnym spotkaniu z klientem i padło trudne pytanie techniczne. Kierownik projektu wtrącił: Michael jest architektem w tym projekcie. Do końca tygodnia to sprawdzi i wyśle ci aktualizację.

I właśnie tak zostałem architektem oprogramowania. Przypływ mocy. Przewidywanie rozwoju kariery. Jestem architektem! Wkrótce ogarnęło mnie uczucie lekkiego strachu. Jestem architektem. Co mam teraz zrobić? Czym różni się architekt oprogramowania od inżyniera oprogramowania?

Architekci oprogramowania poza samym programowaniem mają wiele innych obowiązków. Definiują problem z perspektywy inżynierskiej. Dzielą oni system na części, które można zaimplementować, ale także, mając obraz ogółu, pilnują, aby system nadal działał jako spójna całość. Architekci decydują o kompromisach między atrybutami jakości i zarządzaniem nieuniknionym wzrostem długu technologicznego. Być może przede wszystkim architekci rozwijają umiejętności architektoniczne zespołu, ponieważ wiedzą, że najlepsze zespoły są pełne architektów.

W tym rozdziale przedstawimy, czym zajmują się architekci. Dowiemy się również, dlaczego znajomość architektury oprogramowania sprawi, że będziemy lepszymi programistami i liderami technologicznymi, oraz jak rozpocząć drogę, aby zostać architektem oprogramowania w swojej karierze zawodowej.

Czym zajmują się architekci oprogramowania?

Architekci oprogramowania są na wyjątkowej pozycji w zespole. Nie są kierownikami projektów, ale mają istotny wpływ na termin i sposób dostarczania oprogramowania. Nie są menedżerami produktu, ale odpowiadają za to, że oprogramowanie spełnia swoje cele biznesowe. Programują, ale zarazem projektują coś więcej niż tylko algorytmy i kod. Architekci oprogramowania mają wyjątkowy zestaw obowiązków i faktycznie znajdują się w centrum wszystkiego.

Większość z nas rozpoczyna karierę programistyczną, koncentrując się wyłącznie na technologii. Umiejętność programowania, projektowania skutecznych algorytmów, sprawdzania, czy wszystko działa, a także wdrażania oprogramowania – to podstawowe umiejętności dla architektów oprogramowania. Przejście od programisty do architekta oprogramowania wymaga zaakceptowania nowych obowiązków.

Definiowanie problemu z perspektywy inżynierskiej

Projektowanie architektury oprogramowania jest dyscypliną skoncentrowaną na człowieku. Każdy, kto ma udział w oprogramowaniu, może pomóc w zrozumieniu, czego się od tego oczekuje. Architekci oprogramowania współpracują z menedżerami produktu, kierownikami projektów i innymi interesariuszami, aby określić cele biznesowe i wymagania dotyczące oprogramowania, które ma zostać zbudowane.

W wielu zespołach menedżerowie produktu definiują funkcjonalności. Są one istotne, ale istnieje inny rodzaj wymagań zwany atrybutami jakościowymi, o które architekci dbają najbardziej (patrz Po co stosować atrybuty jakościowe (i inne właściwości systemu), na stronie 10). Oprócz definiowania atrybutów jakościowych systemu architekci zwracają uwagę na ograniczenia projektowe i funkcjonalności, które mogą wymusić na nas określoną ścieżkę architektoniczną.

Definiowanie problemu z myślą o architekturze pozwala zbudować taki system, na jaki każdy czeka. W rozdziale 5: W poszukiwaniu wymagań istotnych dla architektury na stronie 55 dowiemy się, jak architekci podchodzą do wymagań.

Podział systemu i przypisanie odpowiedzialności

Czy kiedykolwiek widzieliście, jak małe dzieci grają w piłkę nożną? Jedyny brzdąc, który pozostaje na pozycji, to bramkarz, przyklejony do bramki swojej drużyny, podczas gdy inne dzieci całą gromadą gonią za piłką z jednego końca pola na drugi. To urocze. Kiedy dzieci trochę dorosną, uczą się rozgrywać na ustawionych pozycjach. Granie na pozycjach jest ważne, ponieważ pozwala trenerowi stworzyć strategię gry, która zwiększa prawdopodobieństwo zdobycia gola przez drużynę.

Niektóre systemy software’owe są zaprojektowane jak dziecięca drużyna piłkarska: jedna wielka grupa oprogramowania goniąca za wydaniem. Tworzenie oprogramowania, podobnie jak w rozgrywkach piłkarskich, przebiega płynniej, gdy oprogramowanie jest podzielone na części, a każdy element ma przypisaną odpowiedzialność, pozycję do grania.

Architekci partycjonują (fantazyjne słowo oznaczające dzielenie na części) system software’owy, dzięki czemu mogą opracować strategię osiągnięcia atrybutów jakościowych i innych wymagań systemowych. Na przykład można podzielić zakres funkcjonalności przez zaprojektowanie jednego komponentu w celu rejestrowania użytkowników, a innego do identyfikacji zdjęć kotów. Lub też można przypisać różne zespoły, aby opracowywały różne moduły, albo też oddzielić rzeczy, które odczytują dane, od rzeczy zapisujących dane, tak aby system oprogramowania był bardziej niezawodny, dostępny i skalowalny.

Partycjonowanie systemu jest ważne nie tylko dlatego, że pozwala opracować strategię osiągnięcia atrybutów jakościowych. Mniejsze fragmenty są łatwiejsze do przemyślenia, łatwiej je przetestować i zaprojektować. Oczywiście, ponieważ podzieliliśmy system na kawałki, musimy również upewnić się, że wszystko się ze sobą poskłada.

Posiadanie szerszego spojrzenia

Każdy system software’owy funkcjonuje w kontekście większego świata. Świat, w którym żyje oprogramowanie, to użytkownicy wchodzący z nim w interakcje, budujący je zespół, sprzęt, na którym działa, a nawet, na pierwszym miejscu, cel stworzenia oprogramowania. Idealnie, architektura powinna żyć w harmonii z tym szerszym kontekstem.

Myślenie o systemie jako całości oznacza, że architekci mają do czynienia z czymś więcej niż tylko technologią. Ludzie, procesy, potrzeby biznesowe i wiele innych czynników technicznych i nietechnicznych odgrywa rolę w ostatecznym systemie software’owym. Nawet proste decyzje projektowe mogą mieć daleko idące konsekwencje. Architekci muszą wychodzić poza bliskie sąsiedztwo decyzji projektowych i myśleć o systemie jako o całości.

Projektowanie oprogramowania to nieustanna walka o znalezienie właściwej równowagi między rzeczami, których chcemy, a rzeczywistością, którą musimy zaakceptować. Oznacza to, że trzeba o tym myśleć i iść na kompromisy.

Wybieranie kompromisów między atrybutami jakościowymi

Powiedzmy, że wysoka dostępność to ważny atrybut jakościowy dla naszych interesariuszy i potrzebujemy oprogramowania, które będzie odpowiadać na 99,9% żądań. Jednym ze sposobów na zapewnienie dostępności jest wprowadzenie redundantnych elementów. Projektowanie tego jest proste, ale istnieje pewien haczyk. Musimy teraz kupić dwa razy więcej sprzętu, co podwoi nasze koszty. W tym przypadku zwiększone zostały koszty, aby uzyskać wyższą dostępność.

Zrezygnowanie z czegoś, by dostać coś, czego potrzebujemy, jest powszechne w rozwoju oprogramowania. Architekci identyfikują kompromisy i pracują z interesariuszami, aby zdecydować, które kompromisy mają największy sens.

Systemy software’owe nigdy nie są idealnie partycjonowane. Idziemy na kompromisy. Popełniamy błędy. W miarę budowania systemu wprowadzamy do architektury dług technologiczny.

Zarządzanie długiem technologicznym

Architekci oprogramowania znają szczegóły dotyczące zależności w systemie. Dostrzegają większą całość i wiedzą, jak to wszystko połączyć. Wiążą także decyzje technologiczne z potrzebami biznesowymi. Wiedza o tym wszystkim stawia architektów w doskonałej pozycji do zarządzania długiem technologicznym.

Dług technologiczny to różnica pomiędzy aktualnym projektem systemu software’owego a projektem, którego potrzebujemy, abyśmy mogli nadal dostarczać określone wartości. Możemy zmierzyć wielkość długu technologicznego, szacując wysiłek wymagany do zniwelowania tej różnicy. Wszystkie programy mają dług technologiczny. Dług technologiczny jest nieuniknionym produktem ubocznym sukcesu. Najlepsze zespoły zajmujące się tworzeniem oprogramowania strategicznie wykorzystują dług technologiczny, by szybciej dążyć do celu i regularnie go zmniejszają, aby zapewnić ciągłe dostarczanie odpowiednich wartości.

Architekci uwidaczniają dług technologiczny i pomagają zainteresowanym stronom zdecydować o tym, jakie działania należy podjąć, aby nim zarządzać.

Rozwijanie umiejętności architektonicznych zespołu

Architekci oprogramowania są nauczycielami i mentorami dla swoich zespołów. Nie ma sensu projektować niesamowitej architektury, której nikt nie może zrozumieć. Obowiązkiem architektonicznego eksperta w swoim zespole jest dzielić się z nim swoją wiedzą, aby można było z powodzeniem tworzyć zadziwiające systemy software’owe.

Architekci uczą umiejętności projektowania i koncepcji architektonicznych dokładnie na czas. Aby przekazać swoją wiedzę, będziemy musieli łączyć projekt z członkami zespołu, tworzyć dokumenty, które będą kształcić i informować, oraz dzielić się konstruktywną krytyką. Być może najważniejszą rzeczą, jaką trzeba będzie zrobić, aby rozwinąć umiejętności architektoniczne zespołu, to włączenie go w proces projektowania. Architektura to działalność społeczna. Rozwój umiejętności jest kluczowy dla sukcesu naszego zespołu.

Teraz już wiemy, co robią architekci, ale jeszcze nie zdefiniowaliśmy, co rozumiemy przez architekturę oprogramowania. Zróbmy coś z tym teraz.

Czym jest architektura oprogramowania?

Architektura oprogramowania systemu jest zbiorem istotnych decyzji projektowych dotyczących organizacji oprogramowania w celu wspierania jego pożądanych atrybutów jakościowych i innych właściwości.

Decyzja projektowa może być ważna z wielu powodów. Może stać się punktem bez powrotu lub wpływać na atrybuty jakościowe, harmonogram lub koszty. Znacząca decyzja może dotyczyć wielu osób lub zmusić do zmiany inne systemy oprogramowania. W każdym przypadku znaczące decyzje projektowe są kosztowne, jeśli chcielibyśmy je później zmieniać, gdyby zostały błędnie podjęte.

Wspieranie atrybutu jakościowego oznacza zachęcanie, aby pojawił się on w systemie oprogramowania. W dobrze zorganizowanej architekturze będzie to wspierać atrybuty jakościowe, które są pożądane przez zainteresowane strony, oraz zminimalizuje lub wyeliminuje te, których nie chcą zainteresowane strony. Architektura może również wspierać inne właściwości. Na przykład odpowiednia organizacja pracy pozwoli na dostarczenie oprogramowania na czas, w ramach budżetu i bez nadmiernych nadgodzin.

Definiowanie podstawowych struktur

Wieżowiec ma fundament i konstrukcję. Ciało ma kości. Oprogramowanie ma struktury. Struktura określa sposób, w jaki system software’owy jest zorganizowany. Struktury są w kodzie, który piszemy, oprogramowaniu, które uruchamiamy, a nawet we współpracy z innymi ludźmi.

Aby utworzyć strukturę, weź dowolny element i połącz go z innym elementem za pomocą związków. Pomyśl o elementach i związkach jak o cegłach i zaprawie oprogramowania. Chleb i masło orzechowe. Taśma klejąca i … cóż, pewnie będziesz mieć jakiś pomysł. Elementy są fundamentalnymi cegiełkami oprogramowania. Związki opisują, w jaki sposób elementy współpracują ze sobą, aby wykonać pewne zadanie.

Łatwo zaprojektować architekturę na papierze bez związku z rzeczywistością. Aby uniknąć tej pułapki, będziemy budować architektury, używając trzech rodzajów elementów i związków. Software Architecture in Practice [BCK12] definiuje te trzy rodzaje jako moduł, komponent i łącznik (ang. component and connector, C&C>) oraz alokację. Aby utworzyć strukturę, należy połączyć elementy i związek tego samego typu.

Oto kilka przykładowych elementów i relacji każdego typu.

Przykładowe elementy

Przykładowe związki

Moduł

klasa, pakiet, warstwa, procedura składowana, moduł, plik konfiguracyjny, tabela bazy danych

używa, może używać, zależy od

Komponent i łącznik

obiekt, połączenie, wątek, proces, warstwa, filtr

wywołanie, subskrybcja, potok, publikowanie, zwrot

Alokacja

serwer, czujnik, laptop, load balancer, zespół, Owen (osoba), kontener Dockera

działa w lub na, odpowiedzialny za, tworzy, przechowuje, płaci

Pyta Joe:

Czy moduły i komponenty to różne byty?

W karierze programistycznej możemy usłyszeć słowa moduł i komponent używane zamiennie i w różnych kontekstach. Z technicznego punktu widzenia komponent to inne pojęcie niż moduł. Moduł odnosi się do elementu na etapie projektu, podczas gdy komponent jest ideą środowiska wykonawczego.

Czasami ta precyzja w języku jest ważna. Używanie terminu o określonym znaczeniu do opisania czegoś ogólnego może wywołać zamieszanie. Za każdym razem, gdy zechcesz generycznie opisać blok architektury, zamiast określać go jako komponent lub moduł, użyj słowa element.

Podsumowując, kłótnie na temat semantyki nie są najlepszym sposobem na przeforsowanie swoich pomysłów. Zachęcam cię do stosowania właściwej i precyzyjnej terminologii, gdyż z czasem twoje pomysły łatwiej będzie zrealizować, jeśli dostosujesz swój język tak, aby inni cię zrozumieli.

Struktury modułowe istnieją na etapie projektowania. Pozostajemy w interakcji ze strukturami modułowymi podczas pisania kodu. Istnieją one w systemie plików i przebywają tam, nawet jeśli oprogramowanie nie jest uruchomione.

Struktury komponentowe i łącznikowe (ang. component and connector structures, C&C) pojawiają się w środowisku wykonawczym. W czasie wykonywania komponenty mogą tworzyć połączenia z innymi komponentami, nowe procesy i instancje nowych obiektów. W przeciwieństwie do struktur modułowych struktury C&C przestają istnieć, gdy system nie jest uruchomiony. Istnienie struktur C&C możemy dostrzec tylko w pozostawianych artefaktach, takich jak plik z logami lub wpis w bazie danych.

Struktury alokacji (ang. allocation structures) są tworzone przez pokazanie, w jaki sposób moduł i elementy C&C korelują ze sobą oraz z fizycznymi elementami istniejącymi w rzeczywistości. Struktury alokacji są czasami nazywane strukturami mapowania, ponieważ pokazują, w jaki sposób poszczególne elementy odnoszą się do innych. Czy element działa na komputerze klienta lub serwerze? Które zespoły budują które części systemu? Struktury alokacji pomagają nam odpowiedzieć na takie pytania.

Różne rodzaje struktur przydają się do myślenia o różnych właściwościach, które chcemy mieć w swoim systemie. Na przykład możemy myśleć o testowalności i zarządzalności przy użyciu struktury modułowej. Struktura C&C pomaga nam zastanawiać się nad oczekiwaniami dotyczącymi środowiska wykonawczego, takimi jak dostępność lub wydajność. Być może zorientujemy się, że istnieje luka w naszym rozumieniu, jeśli zauważymy struktury mieszane, takie jak element statyczny, który używa związku dynamicznego.

Struktury określają kształt naszego systemu. Kształt jest ważny, ponieważ decyduje o atrybutach jakościowych i innych właściwościach, których będą doświadczać użytkownicy. W następnym podrozdziale zobaczymy, jak używać struktur do decydowania o atrybutach jakościowych, ale najpierw czas zabrać się do roboty za pomocą prostego ćwiczenia.

A teraz do dzieła: elementy, związki i struktury

Znajdź kilku członków zespołu z ostatniego projektu. Pracując samodzielnie, zróbcie listę lub naszkicujcie struktury modułów, komponentów i połączeń oraz ich alokacji z tego projektu. Pokażcie swoje listy między sobą. Jak wypada to porównanie? Czy są struktury, które nie zostały zidentyfikowane przez ciebie, a zostały przez członków zespołu? Omówcie podobieństwa i różnice w strukturach zidentyfikowanych przez różnych członków zespołu.

Oto kilka rzeczy do przemyślenia:

- Bądź konkretny podczas nazywania elementów. Nie zapomnij o związkach!

- Zastanów się nad strukturami modułów. Jakie metody lub klasy są używane? Czy klasy znajdują się w różnych pakietach lub przestrzeniach nazw? Jakie zależności są zawarte w menedżerach pakietów lub skryptach budowania?

- Pomyśl o strukturach C&C. Czy oprogramowanie wchodzi w interakcje z innymi procesami lub systemami w trakcie działania? Kto odwołuje się do systemu i jak zmieniają się jego odpowiedzi?

- Zastanów się nad alokacją struktur. Kto jest odpowiedzialny za budowanie różnych części oprogramowania? Jak wdrażane jest oprogramowanie?

Po co stosować atrybuty jakościowe (i inne właściwości systemu)

Załóżmy, że tworzymy aplikację kalkulatora i chcemy dodać dwie liczby. Wydaje się łatwe, prawda?

Chwila. Czy zależało nam na kalkulatorze, który dodaje dwie liczby i jest szybki, niezawodny, skalowalny i łatwy w utrzymaniu? Dlaczego nikt tego nie powiedział!? Gdybyśmy nie spytali o te cechy jakościowe, moglibyśmy zaprojektować zupełnie niewłaściwy system.

Atrybut jakościowy to jakakolwiek zewnętrznie widoczna cecha, dzięki której interesariusze oceniają wartość systemu oprogramowania. Przykłady obejmują skalowalność, dostępność, łatwość konserwacji i testowalność. Doświadczamy tych cech jakościowych podczas interakcji z oprogramowaniem.

Po wybraniu struktury architektonicznej określamy atrybuty jakościowe, na które ma być położony nacisk w systemie software’owym. Myśląc o architekturze oprogramowania, trzeba się upewnić, że projektujemy system oprogramowania, który będzie zapewniał pożądane atrybuty jakościowe, pośród wszystkich innych potrzeb wymagających uwagi.

Atrybuty jakościowe sprawiają, że oprogramowanie jest wyjątkowe. Okoliczności każdego systemu są różne – inny zespół, inny budżet, różne warunki rynkowe, nawet różne trendy technologiczne. W rezultacie nigdy nie będzie dwóch identycznych architektur, nawet jeśli zestawy funkcjonalności są identyczne.

Gotowi stawić czoła wyzwaniu? W następnej części poznamy kilka strategii, aby móc stać się architektem swojego zespołu.

Zostańmy architektami w naszym zespole

W niektórych zespołach architekt jest oficjalną funkcją w zespole. W innych nie ma takiej roli i członkowie zespołu dzielą jego obowiązki. Czasem zespoły mówią, że nie mają architekta, ale jeśli przyjrzymy się uważnie, ktoś wypełnia obowiązki architekta, nie zdając sobie z tego sprawy.

Architekci są liderami, ale bycie architektem oprogramowania również oznacza osobę, która myśli o projektowaniu oprogramowania w określony sposób. Niezależnie od tego, co zawiera tytuł wizytówki (mój nadal wskazuje inżyniera oprogramowania, to mój wybór), można być architektem oprogramowania. Każdy zespół ma co najmniej jednego architekta. Najlepsze zespoły mają ich kilku.

Jeśli nasz zespół nie ma architekta, masz pracę! Nie potrzebujesz pozwolenia na włączanie myślenia architektonicznego w dyskusje projektowe naszego zespołu. Zacznijmy zadawać pytania dotyczące atrybutów jakościowych. Wskażmy, kiedy zespół osiąga kompromisy. Zgłośmy się, aby opisywać decyzje projektowe i zacznijmy akceptować więcej obowiązków związanych z projektowaniem architektury.

Jeśli nasz zespół ma już architekta, spytajmy tej osoby, w jaki sposób możemy jej pomóc. Jeśli to możliwe, ściśle współpracujmy z architektem i wykorzystajmy każdą możliwą okazję do nauki. Opracowanie systemu software’owego to wielka praca. Im więcej osób zwraca uwagę na szczegóły, tym większa szansa na sukces. Każdy zespół powinien być szczęśliwy, mając wielu doświadczonych architektów oprogramowania!

Zróbmy krok od programisty do architekta oprogramowania

Przeciętny architekt oprogramowania ma w dorobku od trzech do pięciu systemów z rosnącą odpowiedzialnością techniczną w każdym z nich. W zależności od budowanego oprogramowania i wraz ze zwiększaniem się liczby obowiązków architektonicznych ma mniej czasu na programowanie. Jest to normalne, chociaż architekci oprogramowania nigdy nie powinni całkowicie przestać programować.

Aby zmierzyć swój rozwój od programisty do architekta oprogramowania, utwórzmy portfolio projektów. Dla każdego stworzonego systemu oprogramowania, bez względu na swoją rolę, krótko opiszmy ten system i to, czego udało nam się nauczyć w tym czasie. Ten rodzaj refleksji jest niezbędny dla wszystkich liderów technologicznych, ale przede wszystkim dla architektów oprogramowania.

Oto kilka pytań, na które należy odpowiedzieć na temat każdego projektu ze swojego portfolio:

- Kim byli interesariusze i jakie były główne cele biznesowe?

- Jak wyglądało wysokopoziomowe rozwiązanie?

- Jakie technologie zostały użyte?

- Jakie były największe zagrożenia i jak udało nam się je pokonać?

- Gdyby można było to zrobić od początku, jak można by było to zrobić inaczej?

Niezależnie czy celem jest awans, czy też po prostu rozwój zawodowy, trzeba być cierpliwym. Szansa na zaprojektowanie systemu oprogramowania o znaczącej złożoności zazwyczaj pojawia się tylko raz na trzy do pięciu lat. Jeśli mamy szczęście, przez całą karierę zobaczymy od 8 do 15 systemów oprogramowania. Trzeba być przygotowanym, aby wykorzystać pojawiające się możliwości tworzenia architektury. Współpracujmy z członkami zespołu, aby dać każdemu szansę na rozwój swoich umiejętności. Obiecuję, że praca architekta jest dla wszystkich bardziej niż interesująca!

Pamiętajmy zawsze, że architekt oprogramowania to sposób myślenia, a nie tylko rola w zespole. Kiedy jesteśmy programistami, podejmujemy dziesiątki decyzji związanych z projektowaniem. Niektóre z tych decyzji mają znaczenie architektoniczne. Każdy, kto podejmuje decyzję, która wpływa na strukturę oprogramowania, staje się architektem pro tempore. Od nas zależy, czy podejmiemy dobre decyzje i zachowamy integralność architektoniczną, niezależnie od tego, co jest napisane na naszej wizytówce.

Budowanie niesamowitego oprogramowania

Jest wiele rzeczy, które muszą się udać podczas budowania systemu software’owego. Architektura łączy je wszystkie razem i stanowi podstawę sukcesu. Oto sześć sposobów ułatwiających zbudowanie przez architekturę oprogramowania spektakularnego oprogramowania, które interesariusze pokochają:

1. Architektura oprogramowania przekształca duży problem w mniejsze, łatwiejsze w zarządzaniu.
Nowoczesne systemy oprogramowania są duże, złożone i mają wiele współdziałających fragmentów. Architektura precyzyjnie wyjaśnia, w jaki sposób podzielić system na mniejsze fragmenty o niewielkich rozmiarach, jednocześnie zapewniając, że system jako całość stanowi większą wartość niż suma jego części.

2. Architektura oprogramowania pokazuje ludziom, jak współpracować.
Rozwój oprogramowania jest związany tak samo z komunikacją międzyludzką, jak i z technologią. Architektura oprogramowania opisuje, jak spaja się cały system, włączając w to też ludzi, którzy go tworzą. Gdy znamy architekturę, wtedy możemy zobaczyć, jak ludzie mogą współpracować przy tworzeniu oprogramowania. Im większy system oprogramowania, tym staje się to ważniejsze.

3. Architektura oprogramowania zapewnia terminologię do mówienia o złożoności pomysłów.
Jeśli nie rozumiemy, o czym mówimy, nie będziemy mogli współpracować. Zamiast spędzać cały czas na wymyślaniu słownictwa i pojęć, możemy wykorzystać podstawowe pojęcia i podstawową terminologię architektury jako fundament współpracy. Wtedy możemy spędzić czas, rozwiązując prawdziwe problemy naszych użytkowników.

4. Architektura oprogramowania wykracza poza cechy i funkcjonalność.
Cechy i funkcjonalności są ważne, ale to nie jedyna rzecz, która określa, czy oprogramowanie jest niesamowite. Projektując architekturę, bierzemy pod uwagę nie tylko cechy, lecz także koszty, ograniczenia, harmonogramy, ryzyko, zdolność zespołu do wykonania, a przede wszystkim atrybuty jakościowe – takie jak skalowalność, dostępność, wydajność i łatwość utrzymania.

5. Architektura oprogramowania pomaga uniknąć kosztownych błędów.
W Who Needs an Architect? [Fow03], Martin Fowler definiuje architekturę oprogramowania: „to ważna rzecz. Cokolwiek nią jest”. Ważne rzeczy są prawie zawsze tym, co uważamy za trudne do zmiany bez znaczącego zwiększenia złożoności. Grady Booch nawiązuje do opinii Fowlera, definiując architekturę jako „istotne decyzje projektowe (gdzie istotność jest mierzona kosztem zmian)”[2]. Architekci oprogramowania nie są wszechwiedzący, ale zaprojektowanie architektury pomoże odkryć trudne (i interesujące) części problemu, które mogą później sprawiać duże kłopoty.

6. Architektura oprogramowania umożliwia zmienność.
Oprogramowanie powinno reagować na zmiany jak woda, z łatwością pokonując przeszkody. Jeśli oprogramowanie jest jak woda, zdolne przybrać dowolny kształt, architektura oprogramowania to pojemnik, który je przechowuje. Ten pojemnik może być sztywny jak pudełko lub elastyczny jak plastikowa torba. Może być gruby i ciężki lub lekki. Bez architektury oprogramowanie, podobnie jak woda, podąża ścieżką najmniejszego oporu i niekontrolowanie się rozwija. Architektura systemu oprogramowania zapewnia strukturę, w ramach której zmiana jest możliwa.

Przez resztę książki będziemy rozwijać te stwierdzenia.

Studium przypadku: Projekt Lionheart

Po omówieniu nowych idei w poszczególnych rozdziałach zastosujemy je do studium przypadku – Projektu Lionheart. Opiera się ono na prawdziwym systemie, ale nazwy i sytuacje zostały zmienione w celach dydaktycznych i prawnych.

Projektowanie architektury w celu rozwiązania tego problemu

Miasto Springfield stoi w obliczu braków w budżecie i konieczności ograniczenia kosztów. Burmistrz Jean Claude van Damme (bez związku z bohaterem kina akcji) zatrudnił nasz zespół do usprawnienia Biura Zarządzania i Finansów (BZF).

Kiedy pracownik miejski musi kupić coś za więcej niż kilka tysięcy dolarów, BZF publikuje Zapytanie Ofertowe (ZO) w lokalnej gazecie. Przedsiębiorcy składają oferty w odpowiedzi na ZO, a BZF podpisuje umowę na podstawie konkurencyjności oferty i innych czynników. BZF monitoruje ponad 500 aktywnych umów i zapytań ofertowych dotyczących wszystkiego, od papieru toaletowego przez artykuły medyczne aż po piłki do koszykówki. BZF zarządza wszystkimi tymi danymi za pomocą arkuszy kalkulacyjnych.

Burmistrz van Damme ma nadzieję, że unowocześnienie BZF poprawi kilka strategicznych obszarów.

- Dla ponad połowy wszystkich ZO została złożona jedna oferta. Potencjalnie miasto przepłaca za usługi o niższej jakości.

- Finalizacja umowy trwa miesiącami. Wiele firm gubi się w tym wieloetapowym procesie.

- Publikacja nowego ZO zajmuje do 6 tygodni. Ten proces musi być krótszy.

W części II omówimy to studium przypadku i wspólnie opracujemy potencjalną architekturę, aby rozwiązać niektóre z tych problemów.

Co dalej

Architekci oprogramowania są odpowiedzialni za całkiem sporo rzeczy. Projektowanie ciekawych, złożonych systemów oprogramowania i praca z różnymi ludźmi dają dobre samopoczucie i są warte wysiłku. Architektem oprogramowania nie zostanie się w jedną noc. Staniemy się świetni, jeśli będziemy skupiać się na głównych zadaniach architekta i zrobimy to, co w naszej mocy, aby zastosować podstawy architektoniczne polegające głównie na wyborze struktur, które będą sprzyjać pożądanym atrybutom jakościowym.

W tym rozdziale zostało przedstawione, czym jest architektura i czym zajmują się architekci. W następnym rozdziale dowiemy się, jak używać myślenia projektowego, aby zorientować się, co powinno stać się składnikiem architektury.

ROZDZIAŁ 2

Podstawy myślenia projektowego

W pierwszym dniu pracy z dowolnym systemem oprogramowania najpierw trzeba odkryć architekturę. Niezależnie od tego, czy zaczynamy od czystej kartki, czy musimy odkryć struktury w istniejącym systemie, potrzebna architektura gdzieś tam jest, oczekując na odkrycie. Aby zaprojektować architekturę systemu oprogramowania, analizujemy potencjalne rozwiązania, a równolegle pracujemy nad poznaniem problemu do rozwiązania.

Aby pomóc sprostać temu wymagającemu wyzwaniu, nauczymy się twórczego i analitycznego podejścia do rozwiązywania problemów, które stawia ludzi w centrum zainteresowania i jest zwane myśleniem projektowym. Skoncentrowanie się na ludziach, na których będą miały wpływ decyzje projektowe, pomaga skupić się na istocie problemów, które należy rozwiązać. To także uzasadnia nasze poszukiwania rozwiązań, przypominając, że celem jest tworzenie oprogramowania, które pomaga ludziom.

W tym rozdziale dowiemy się, jak zastosować myślenie projektowe w architekturze oprogramowania. Zaczniemy od poznania podstawowych zasad myślenia projektowego. Następnie nauczymy się wykorzystywać różne sposoby myślenia projektowego, aby utrzymać rozwój architektury (w większości) we właściwym kierunku. Na koniec zobaczymy podejście do kreowania nastawienia projektowego.

Cztery zasady myślenia projektowego

Myślenie projektowe jest mniej procesem, a bardziej sposobem myślenia o problemach i rozwiązaniach z perspektywy osób, które się z nimi zetknęły. Chociaż nie jest ono procesem, to istnieją zasady, według których należy stosować działania projektowe. W Design Thinking: Understand – Improve – Apply (Understanding Innovation) [PML10] Christoph Meinel i Larry Leifer proponują cztery uniwersalne reguły projektowania. Zasady te dotyczą zarówno architektury oprogramowania, jak i szczegółowego projektu programu, interakcji z użytkownikiem lub innej dyscypliny ukierunkowanej na projektowanie.

Oto cztery reguły projektowania:

1. Reguła ludzka (ang. Human rule). Cały projekt ma charakter społecznościowy.

2. Reguła niejednoznaczności (ang. Ambiguity rule). Zachowajmy niejednoznaczność.

3. Reguła przeprojektowywania (ang. Redesign rule). Cały projekt to przeprojektowanie.

4. Reguła namacalności (ang. Tangibility rule). Uczyńmy pomysły namacalnymi dla ułatwienia komunikacji.

Będziemy używać akronimu HART (ang. human, ambiguity, redesign, tangibility), aby pomóc zapamiętać te zasady. Przyjrzyjmy się zasadom HART w tym zakresie, w jakim odnoszą się one do projektowania architektury oprogramowania, dzięki czemu możemy zobaczyć, jak zastosować myślenie projektowe w kontekście tego typu systemów.

Projektowanie dla ludzi

Projekt jest przedsięwzięciem skoncentrowanym na człowieku. Projektujemy oprogramowanie dla ludzi. Projektujemy oprogramowanie z ludźmi. Każda decyzja projektowa w architekturze w jakiś sposób pomaga osobom. Zarazem każda taka decyzja musi być zrozumiana i udostępniona innym osobom.

Architekci muszą wczuć się we wszystkich interesariuszy. Trzeba dbać o użytkowników końcowych tak samo jak o ludzi, którym pomagają użytkownicy końcowi, programistów, którzy piszą kod, testerów, którzy go weryfikują, a nawet menedżerów, którzy pilnują harmonogramu projektu. Gdy projektujemy system oprogramowania, będziemy współpracować z pozostałymi osobami z naszego zespołu i okazywać szacunek, słuchając ich, zakładając pozytywne intencje oraz stosując metody projektowania ukierunkowane na człowieka.

Reguła ludzka przypomina również, że architekci nie są oddzieleni od zespołów. Współpracujemy bezpośrednio z nimi, aby wspólnie projektować architekturę. Budowanie oprogramowania to intensywna aktywność społeczna. Idea architekta w wieży z kości słoniowej, który projektuje architekturę izolowany od zespołu, jest mitem. Architekci oprogramowania stanowią integralną część każdego zespołu. Oddzielenie architekta od zespołu odcina połączenie między architektem a wszystkimi, których architektura będzie dotyczyć.

Empatia w stosunku do ludzi, którzy bezpośrednio i pośrednio wchodzą w interakcję z architekturą, czyni nas lepszym projektantem, komunikatorem i liderem.

Zachowywanie niejednoznaczności

Niejednoznaczność w inżynierii jest niebezpieczna. Po podjęciu decyzji projektowej musimy podzielić się nią z precyzją i jasnością. Pozwolić, aby wymagania, decyzje projektowe i zobowiązania pozostały niejednoznaczne, to najlepszy sposób na zniszczenie projektu. Zanim zatwierdzimy decyzję projektową, możemy użyć niejednoznaczności, aby zachować otwarte możliwości.

Ponieważ celem architektury oprogramowania jest stworzenie struktur promujących pożądane cechy jakościowe, to na nich skupimy naszą uwagę. W Less is more with minimalist architecture [MB02], Ruth Malan i Dana Bredemeyer sugerują architektom zaprojektowanie minimalistycznej architektury. Minimalistyczna architektura pokazuje tylko, jak osiągane są atrybuty jakościowe o wysokim priorytecie i zmniejsza ryzyko związane z lansowaniem tych atrybutów jakościowych. Wszystkie inne decyzje projektowe pozostawia się otwarte dla projektantów niższego szczebla.

Architektoniczny minimalizm sugeruje, że chcemy odroczyć wiążące decyzje projektowe tak długo, jak jest to możliwe. Decyzje projektowe, które nie wpływają bezpośrednio na atrybut jakościowy lub zmniejszają ryzyko zagrażające naszej zdolności do dostarczenia oprogramowania, w większym stopniu dotyczą szczegółowego projektu niż architektury. Takie decyzje można bezpiecznie pozostawić jako otwarte dla projektantów niższego szczebla, aby mogły zostać umieszczone poza architekturą. Dowiemy się więcej o zachowaniu niejednoznaczności w podrozdziale Projektowanie z myślą o zmianach na stronie 84.

Zachowanie niejednoznaczności pozwala nam dostarczać oprogramowanie, nawet gdy zmienia się świat wokół nas.

Projektowanie jest przeprojektowywaniem

W A Pattern Language: Towns, Buildings, Construction [AISJ77], Christopher Alexander i współautorzy skatalogowali ponad 253 problemy inżynierii lądowej ze znanymi, dobrymi rozwiązaniami. Tematy różniły się, począwszy od materiałów budowlanych po sposoby organizacji społeczności oraz architekturę budynków. Jeśli kiedykolwiek dane nam było się cieszyć doskonałym wiosennym porankiem, popijając kawę w ulicznej kawiarni, możemy podziękować Christopherowi Alexandrowi za udokumentowanie wzoru ulicznej kafejki jako rozwiązania budującego społeczność.

Reguła przeprojektowania zachęca nas do zastanowienia się nad tym, co już wiemy dzięki zbieraniu wzorców i projektów z przeszłości. W miarę upływu czasu i tworzenia następnego oprogramowania zwiększa się nasza instytucjonalna wiedza na temat projektowania doskonałego oprogramowania. Inne zespoły prawdopodobnie natknęły się na problem podobny do tego, z którym obecnie się spotykamy. Mamy nadzieję, że ktoś udokumentował wzorzec, który możemy wykorzystać jako punkt wyjścia dla naszej architektury. Może ktoś zbudował framework zaprojektowany do rozwiązania dokładnie takiego problemu jak nasz?

Podczas projektowania architektury oprogramowania więcej czasu poświęcimy na udoskonalanie istniejących projektów niż na tworzenie nowych. Jednym z najmniej efektywnych sposobów projektowania architektury oprogramowania jest ignorowanie systemów oprogramowania, które powstały wcześniej.

Sprawmy, aby architektura była namacalna

Chociaż struktury w architekturze mogą znajdować się w kodzie, nie powoduje to, że architektura staje się bardziej namacalna. Kod jest trudny do odczytania i nie ułatwia dyskusji o atrybutach jakościowych, gruboziarnistych komponentach, uzasadnieniach projektowych lub konsekwencjach decyzji. Jeśli chcemy dzielić się architekturą z innymi, musimy ją urealnić, na co kod sam w sobie nie pozwoli.

Istnieje wiele sposobów na uczynienie architektury namacalną. Narysujmy ją. Sprawmy, by ożyła w kodzie, który napiszemy. Utwórzmy prototypy, które pozwolą ludziom doświadczyć struktur i atrybutów jakościowych. Stwórzmy proste modele pokazujące, jak działa część architektury. Twórzmy rozpoznawalne metafory. Przedstawmy fragment sterowania przepływem w systemie.

Reguła namacalności jest ściśle związana z regułą ludzką. Ludzie muszą opowiedzieć się za ideą, by ją zaakceptować. Jedynym sposobem na podzielenie się architekturą jest uczynienie jej namacalną.

Zasady HART stanowią filozoficzną podstawę naszego podejścia do projektowania architektury. Kierują one naszymi decyzjami i przenikają nasze myślenie. Te cztery zasady opisują, dlaczego robimy rzeczy w ten, a nie inny sposób. Teraz, gdy rozumiemy podstawowe zasady stojące za myśleniem projektowym, zastanówmy się, jak je zastosować, ucząc się wybierania praktyk projektowych ukierunkowanych na architekturę.

Zastosowanie nastawienia projektowego

Projektowanie systemu software’owego wymaga od nas myślenia o architekturze z perspektywy różnych nastawień projektowych (ang. design mindsets). Nastawienie projektowe jest sposobem myślenia o świecie, dlatego skupiamy naszą uwagę na właściwych detalach we właściwym czasie.

Istnieją cztery nastawienia projektowe: zrozumienie, badanie, tworzenie i ocenianie. Z każdym nastawieniem projektowym związany jest zestaw praktyk. Aby zaprojektować architekturę, trzeba wybrać nastawienie, praktykę z danego nastawienia, zastosować ją, aby dowiedzieć się czegoś nowego o architekturze, a potem to powtarzać.

W rozdziałach części II pokażemy, jak zastosować w praktyce każdy rodzaj nastawienia. Na początku każdego rozdziału jedna z ikon pokazanych na rysunku na stronie 19 będzie wskazywać, na co będzie kładziony nacisk. Przekonajmy się teraz, co oznacza każdy z czterech sposobów nastawienia projektowego.

Zrozumienie problemu

W nastawieniu na zrozumienie aktywnie poszukujemy informacji od interesariuszy i pracujemy nad opisem problemu. W tym nastawieniu są tak samo ważne wymagania jak i empatia. Aby zrozumieć problem, musimy dowiedzieć się czegoś na temat potrzeb osób, które będą miały do czynienia z naszym systemem.

Aby zrozumieć problem, musimy zbadać cele biznesowe i atrybuty jakościowe, które są ważne dla naszych interesariuszy. Będziemy musieli również dowiedzieć się, jak działa nasz zespół i zyskać lepsze wyczucie priorytetów i kompromisów między decyzjami projektowymi.

Badanie pomysłów

W popularnym wyobrażeniu myślenie projektowe to burza mózgów i karteczki samoprzylepne. Burza mózgów jest skuteczna, ale to tylko jedna z praktyk w nastawieniu na badanie. Podczas badania tworzymy wiele koncepcji projektowych i identyfikujemy podejścia inżynierskie w celu rozwiązania pewnego aspektu problemu.

Odkrywanie architektury oprogramowania oznacza, że próbujemy kombinacji struktur, dopóki nie znajdziemy kombinacji, która najlepiej odpowiada pożądanym atrybutom jakościowym. Aby znaleźć najlepszą kombinację struktur, musimy zbadać szeroki zakres wzorców, technologii i praktyk rozwojowych. Kiedy planujemy architekturę, spędzimy dużo czasu, nastawiając się na odkrywanie, ale jest ono również przydatne w pracy z interesariuszami.

Urzeczywistnianie

Jak nauczyliśmy się w Sprawmy, aby architektura była namacalna na stronie 20, pomysły są świetne, ale jeśli nie możemy przenieść ich ze swojego mózgu do czyjegoś, wtedy są bezużyteczne. Dzięki ich urzeczywistnieniu możemy je udostępnić, ale także mamy szansę na przetestowanie pomysłu. W nastawieniu na tworzenie przenosimy nasze koncepcje projektowe na artefakty z prawdziwego świata.

Najczęstszym sposobem, w jaki możemy urzeczywistnić architekturę, jest stworzenie modeli. Tworzenie daleko wykracza poza pudełka i linie na diagramach. Możemy urzeczywistnić architekturę, budując prototypy, pisząc dokumentację, wykonując obliczenia i stosując różne inne podejścia.

Nastawienie na tworzenie jest przydatne przy komunikowaniu naszych planów. Urzeczywistniamy architekturę także wtedy, gdy budujemy system – na przykład organizując nasz kod tak, aby można było zobaczyć struktury modułów w architekturze. Tworzenie to także doskonały sposób na wypchnięcie zespołu z paraliżu analizy.

Ocenianie dopasowania

Skąd wiadomo, czy decyzja projektowa rozwiąże problem? Kiedy przyjmujemy nastawienie na ocenianie, możemy określić dopasowanie decyzji projektowych w stosunku do naszego obecnego rozumienia.

Ocenianie to nie wybór wszystko albo nic. Możemy ocenić całą architekturę lub część architektury, nawet tylko pojedynczy model, koncepcję lub pomysł. Najbardziej powszechnym podejściem jest zbadanie fragmentu architektury za pomocą różnych scenariuszy, ale można również testować decyzje projektowe, przeprowadzając bezpośrednie eksperymenty lub badając ryzyko związane z decyzją.

Nastawienie na ocenianie przydaje się, gdy chcemy zweryfikować planowaną lub stworzoną architekturę, ale to dopiero początek. To nastawienie pomoże nam sprawdzić wszystko, co robimy i zdecydować, czy dany artefakt przysłuży się temu, czego potrzebujemy.

Korzystanie z nastawień projektowych wymaga procesu ze ścisłymi informacjami zwrotnymi, dzięki czemu możemy szybko przejść od jednego nastawienia do innego. W następnym podrozdziale dowiemy się, jak korzystać z prostego, powtarzalnego podejścia, które pomoże w wyborze i użyciu nastawienia projektowego.

A teraz do dzieła: zrozumienie, badanie, tworzenie, ocenianie

Cztery rodzaje nastawień projektowych odzwierciedlają sposób, w jaki ludzie rozwiązują problemy. Nawet bez przeszkolenia w myśleniu projektowym prawdopodobnie tych nastawień używałeś już wcześniej. Jakie są przykłady zastosowania przez ciebie każdego z tych nastawień projektowych w twojej karierze tworzenia oprogramowania? Spróbuj wymienić co najmniej dwa przykłady, jak ci się pracowało w każdym z nastawień projektowych.

Oto kilka rzeczy do przemyślenia:

- Kiedy współpracowałeś z ludźmi w celu zrozumienia problemu? Czy stosowano określoną metodę?

- W jaki sposób układała się współpraca z innymi, aby badać pomysły i stworzyć warianty?

- A pomijając kod – w jaki sposób rzeczy, które zostały wytworzone, zmieniły sposób współpracy z interesariuszami i członkami zespołu?

- Jak były oceniane projekty? Jakie techniki wykorzystałeś do testowania hipotez rozwiązań?

Myślenie, robienie, sprawdzanie

Każdego dnia, kiedy pracujemy nad oprogramowaniem, uczymy się ciekawych rzeczy na jego temat. Każda nowa rzecz, której się dowiadujemy, może zmusić architekturę do zmian, aby pogodzić ją z nowymi informacjami. Abyśmy mogli nadal śledzić ten nieustannie zmieniający się krajobraz, potrzebujemy podejścia projektowego z pętlą przyczynowo-skutkową, która daje nam możliwość częstej zmiany naszego myślenia.

W naszym podejściu są trzy kroki: myślenie, robienie i sprawdzanie. Każda iteracja cyklu „myślenie-robienie-sprawdzanie” skupia się na konkretnym nastawieniu projektowym.

Iterowanie w celu uczenia się

Iteracja może trwać zaledwie kilka minut lub kilka dni. Preferujemy cykle krótsze niż dłuższe, ale czasem potrzeba więcej czasu na dogłębne badania. Każda iteracja przebiega zgodnie z tymi samymi krokami, ale wykonanie będzie się różnić w zależności od przyjętego przez nas nastawienia projektowego.

Myślenie Czego mamy nadzieję się nauczyć? Na jakie pytania potrzebujemy odpowiedzi? Czym najbardziej ryzykujemy? Myślenie obejmuje stworzenie planu, aby dowiedzieć się, czego potrzebujemy w celu odpowiedzenia na konkretne pytania lub zmniejszenia ryzyka.

Robienie Wykonajmy plan. Stwórzmy coś namacalnego, coś co szybko i bez większych nakładów finansowych ujawni informacje potrzebne do sprawdzenia naszego myślenia i podzielenia się naszymi pomysłami.

Sprawdzanie Krytycznie sprawdźmy, co osiągnęliśmy podczas kroku robienie, abyśmy mogli zdecydować o naszym następnym ruchu. Wnioski z kroku sprawdzanie informują nas, co dalej. Powtarzajmy od etapu myślenie.

System oprogramowania nigdy nie jest ukończony; jest tylko wydany. Ponieważ oprogramowanie nigdy nie jest ukończone, nasze podejście do projektowania nie ma końca. Stosujemy to samo podejście za każdym razem, gdy musimy zrewidować jakiś aspekt architektury, niezależnie od tego, czy jest to rozwój istniejącego projektu, czy stworzenie czegoś nowego.

Stosowanie nastawień w dowolnej kolejności

Pomyślmy o czterech nastawieniach projektowych jak o czterech skrzynkach narzędziowych, z których każda zawiera narzędzia dostosowane do konkretnego rodzaju prac projektowych. Gdy zajdzie taka potrzeba, zastosujmy nastawienie wymagane, aby dowiedzieć się więcej o świecie lub zmniejszyć ryzyko.

W nastawieniu na zrozumienie koncentrujemy się na potrzebach interesariuszy i określeniu tych potrzeb jako wymagań. W nastawieniu na badanie będziemy zastanawiać się nad sposobami rozwiązania problemu, zgodnie z tym jak rozumiemy go, patrząc na wzorce, technologie i inne rozwiązania. W nastawieniu na tworzenie będziemy modelować system, zatem będziemy mieli coś konkretnego do przemyślenia i udostępnienia. W nastawieniu na ocenianie przekazujemy do testów nasze modele i wymagania.

Nastawienia zmieniają się często i szybko. Podczas jednej rozmowy możemy zmieniać je kilka razy. Podczas warsztatów stworzymy sytuacje, które zmuszą uczestników do przyjęcia nowych nastawień, abyśmy mogli osiągnąć pożądany rezultat. Przykład znajduje się w rozdziale 9: Prowadzenie architektonicznych warsztatów projektowych na stronie 123.

Doświadczeni architekci często nie zdają sobie sprawy, że podchodzą do architektury z różnych perspektyw. Poruszają się instynktownie i instynktownie przyjmują różne nastawienia (dzięki wieloletniej praktyce). Znajomość czterech nastawień projektowych daje nam nowe techniki wydostania się z rutyny. Jeśli utkniemy, wybierzmy nowy sposób myślenia, aby ruszyć do przodu.

Określanie kursu: myślenie-robienie-sprawdzanie oraz nastawienia w działaniu

Zobaczmy konkretny przykład tego, w jaki sposób w praktyce może funkcjonować cykl myślenie-robienie-sprawdzanie oraz nastawienia projektowe. Powiedzmy, że od interesariusza otrzymaliśmy nowe ograniczenie, a to zwiększa ryzyko, że architektura nie będzie w stanie spełnić wymagań wydajnościowych.

- Myślenie. Wiemy, że wydajność systemu jest ważna, ale nie wiemy, co to znaczy mieć dobrą wydajność. Ponieważ potrzebujemy informacji o problemie, zastosujmy nastawienie na zrozumienie. Po przejrzeniu niektórych praktyk z rozdziału 14: Działania na rzecz zrozumienia problemu na stronie 205, decydujemy się na zastosowanie scenariuszy atrybutów jakościowych.

- Robienie. Przeprowadzamy burzę mózgów dotyczącą różnych scenariuszy wydajnościowych i zapisujemy je w dokumencie.

- Sprawdzanie. Zespół i zainteresowane strony zapoznają się ze scenariuszami i przekazują opinie.

Opieramy się na tym, czego nauczyliśmy się, i wówczas pojawiają się nowe zagrożenia. Czy możemy zrealizować scenariusze atrybutów jakościowych związanych z wydajnością przy uwzględnieniu nowego ograniczenia?

- Myślenie. Ponieważ musimy zweryfikować, czy nasze decyzje spełniają określony atrybut jakościowy, zastosujmy nastawienie na ocenianie. Planujemy eksperyment, abyśmy mogli bezpośrednio przetestować wpływ ograniczenia na wydajność.

- Robienie. Piszemy proste skrypty, aby sterować istniejącymi częściami systemu oprogramowania i zbierać dane. Przeprowadzamy eksperyment.

- Sprawdzanie. Dysponując danymi, sprawdzamy wyniki i stwierdzamy, że nowe ograniczenie negatywnie wpływa na wydajność, chociaż tylko o kilkaset milisekund.

Uważamy, że wykonaliśmy dobrą robotę, a pogorszenie wydajności jest śmieszne. Zmniejszenie wydajności może nie być wielkim problemem, dopóki nie spadnie zbyt mocno. Musimy podzielić się tymi wynikami z naszymi interesariuszami i omówić implikacje nowego ograniczenia.

- Myślenie. Ponieważ urzeczywistnianie pomysłów ułatwia komunikację, zastosujemy nastawienie na tworzenie i zbudujemy prosty prototyp. Chcemy, aby interesariusze przekonali się o wpływie nowego ograniczenia. Wykresy nie wystarczą.

- Robienie. Opracowujemy prototyp, który demonstruje działanie aplikacji i symuluje różne założenia dotyczące wydajności.

- Sprawdzanie. Dajemy prototyp naszym interesariuszom i wyjaśniamy, dlaczego wydajność systemu została zmniejszona. Na papierze kilkaset milisekund to niewiele, ale bezpośrednie doświadczenie spowolnienia pokazuje, że spadek wydajności nie jest akceptowalny.

Prototyp pomógł naszym interesariuszom dowiedzieć się czegoś o problemie, o którym nikt do tej pory nie myślał, że jest ważny. Potem stosujemy nastawienie na zrozumienie i szczegółowo redefiniujemy nowe wymagania. Na tym samym spotkaniu przez kilka minut sprawdzamy nasze zrozumienie, stosując nastawienie na badanie. Cykl trwa.

Cykl myślenie-robienie-sprawdzanie jest niezwykle elastyczny. Jak go użyjemy, zależy od złożoności i wielkości systemu, rozmiaru i umiejętności naszego zespołu oraz naszych doświadczeń z tworzeniem w locie nowych inicjatyw projektowych.

Co dalej

Myślenie projektowe daje nam sposób na połączenie wysoce technicznego świata oprogramowania komputerowego z ludźmi, którzy zetknęli się z tworzonym przez nas oprogramowaniem. Cztery zasady HART są środkiem, w jaki damy naszemu oprogramowaniu serce (100-procentowy kalambur). Nastawienia projektowe to sposoby, za pomocą których decydujemy, co należy zrobić, aby pomóc naszym interesariuszom.

Teraz, gdy omówiliśmy teorię, czas przejść do działania.

Od czasu wynalezienia oprogramowania zastanawialiśmy się, ile propozycji zaprojektowania architektury systemu pojawia się na początku, a ile nowych pojawia się w trakcie implementacji. Jak w każdej dyskusji na temat skrajności, właściwa odpowiedź leży gdzieś pośrodku. W następnym rozdziale zobaczymy, jak zdefiniować strategię projektowania odpowiednią do naszej sytuacji i jak wybrać nastawienia projektowe, biorąc pod uwagę ryzyka w systemie oprogramowania.

Część II

Podstawy projektowania architektury

W części I poznaliśmy zasady myślenia i nastawienia projektowego. W części II dowiemy się, w jaki sposób zastosować te zasady i sposoby myślenia w projektowaniu architektury oprogramowania.

ROZDZIAŁ 3

Opracowywanie strategii projektowania

Projektowanie architektury oprogramowania zawsze wydaje się nieco chaotyczne. Mimo zawirowań i niepewności, które dotyczą każdego systemu oprogramowania, ważne jest, aby mieć plan. Dzięki solidnej strategii projektowania możemy przejść drogą, pokonując mgiełkę niepewności.

Myślenie projektowe jest idealne do znajdowania rozwiązań złożonych problemów. Zamiast próbować skutecznie rozwiązać problem od razu przy pierwszej próbie, myślenie projektowe kładzie nacisk na uczenie się i eksperymentowanie. Testowanie architektury może się nie udać bez jej implementacji, ale można weryfikować elementy architektury przyrostowo w miarę ich projektowania. Mamy możliwość użycia nastawień projektowych oraz cyklu myślenie-robienie-sprawdzanie, aby zdecydować, na czym w kolejnym kroku skupić naszą uwagę.

W rozdziale 2: Podstawy myślenia projektowego na stronie 17 nauczyliśmy się podstawowych zasad myślenia projektowego oraz sposobów zastosowania nastawień projektowych. W tym rozdziale nauczymy się wybierać nastawienia projektowe jako część szerszej strategii projektowania, myśląc o zagrożeniach w systemie oprogramowania.

Poszukiwanie satysfakcjonującego projektu

W racjonalnym świecie problem byłby przez nas w pełni zidentyfikowany, zanim zaprojektowalibyśmy idealną architekturę, która by go rozwiązywała. Szkoda, że nie żyjemy w idealnym, racjonalnym świecie. W The Sciences of the Artificial [Sim96] Herbert Simon ukuł termin ograniczonej racjonalności, aby opisać teoretyczną barierę stworzoną przez ograniczenia czasu, pieniędzy, umiejętności i wiedzy, które sprawiają, że racjonalne projektowanie stanowi wyzwanie dla złożonych problemów, takich jak architektura oprogramowania.

Zamiast racjonalnie poszukiwać optymalnego projektu, staramy się znaleźć architekturę, która jest satysfakcjonująca. Satysfakcjonujący projekt jest także wystarczający – wystarczająco dobry – dla naszych potrzeb.

Zamiast myśleć o architekturze oprogramowania jako o problemie optymalizacji projektu, będziemy szukać satysfakcjonującego projektu, podkreślając następujące działania.

Traktowanie rozwiązań jako eksperymentów. Architekci nie są wszechwiedzącymi mędrcami technologii. Potraktujmy każde potencjalne rozwiązanie jako eksperyment do sprawdzenia. Im wcześniej, szybciej i taniej będziemy mogli potwierdzić (lub unieważnić) nasze hipotezy, tym wcześniej znajdziemy właściwą kombinację struktur, które pomogą naszym interesariuszom oraz tym szybciej nasi interesariusze zyskają na naszych projektach.

Koncentracja na zmniejszaniu ryzyka. Wartość to tylko jedna zmienna, którą należy wziąć pod uwagę. Architektura jest podstawą systemu oprogramowania. Jeśli ona zawiedzie, to zawiedzie wszystko. Architekci muszą wciąż martwić się, co może pójść źle i projektować tak, aby brać pod uwagę takie scenariusze. Możemy wykorzystać ryzyko, aby pomogło nam zdecydować, na czym mamy się następnie koncentrować.

Działania w celu uproszczenia problemów. Proste problemy często mają proste rozwiązania. Istnieje wiele sposobów na uproszczenie problemu. Zmniejszenie liczby zainteresowanych stron zmniejszy różnorodność konkurencyjnych perspektyw, które wpływają na system. Dodawanie lub usuwanie ograniczeń albo też skupianie się na fragmencie problemu może zmniejszyć jego złożoność. Identyfikacja typowych problemów ułatwia skupienie się na przeprojektowywaniu. Typowe problemy mają znane rozwiązania, dlatego możemy zacząć od katalogów ze wzorcami i wykorzystywać nasze zbiorowe doświadczenie podczas poszukiwania rozwiązań.

Szybkie iteracje to szybka nauka. Im szybciej się uczymy, tym więcej możemy odkryć i tym więcej zaufania mamy do naszych rozwiązań. Jeśli się mylimy, dowiedzmy się tego tak szybko, jak to możliwe. Szybki upadek oznacza szybką naukę. Preferujmy krótkie, mocno skonkretyzowane iteracje projektowe z konkretnymi wynikami zamiast długich iteracji projektowych, które koncentrują się wyłącznie na abstrakcyjnych celach.

Myślenie w tym samym czasie o problemie i rozwiązaniu. W Notes on the Synthesis of Form [Ale64] Christopher Alexander pokazuje, że problemy są zawsze definiowane z myślą o rozwiązaniu. Granicę wokół problemu tworzą te rozwiązania, które mogłyby go rozwikłać. Aby zrozumieć problem, musimy odkrywać rozwiązania. Aby lepiej je przeanalizować, musimy uzupełnić naszą wiedzę na temat problemu. Projektowanie architektury oprogramowania wymaga jednoczesnego myślenia o problemach i rozwiązaniach. Pisanie kodu na wczesnym etapie projektowania jest jedną ze strategii radzenia sobie z wzajemnym związkiem między problemami i rozwiązaniami.

Unikanie racjonalnego projektowania nie oznacza, że nagle stajemy się irracjonalnymi architektami. Architektura jest podstawą każdego systemu oprogramowania, zatem nadal potrzebujemy wykonać pewne prace projektowe z góry. Musimy zdecydować, jaką część architektury zaprojektujemy z góry i jak duża powstanie wraz z upływem czasu. Wczesne wybranie strategii projektowania w życiu systemu oprogramowania powie naszemu zespołowi, jak chcemy rozwijać architekturę i wzbudzi zaufanie u naszych interesariuszy.

Decydowanie, ile zaprojektować na początku

Architektura jest niezbędną inwestycją. Każdy system oprogramowania ma architekturę. Tak czy inaczej jej projektowanie zajmie nam ileś czasu. Jeśli na początku zajmiemy się projektowaniem architektury, to zmniejszymy koszty przyszłych przeróbek. Oczywiście, planowanie architektury opóźni również wdrożenie, a potencjalnie opóźni rezultat dla interesariuszy. Jeśli na początku nie poświęcimy czasu na architekturę, to z dużym prawdopodobieństwem będziemy musieli wprowadzić zmiany w architekturze po opracowaniu części oprogramowania.

W zależności od wielkości systemu oprogramowania i jego wymagań każdy system oprogramowania ma projektowy złoty środek, optymalną ilość czasu przeznaczoną na zaprojektowanie architektury przed zajęciem się implementacją.

Znajdowanie projektowego złotego środka

W Architecting: How Much and When? [BWO10] Barry Boehm pokazuje nam, że połączenie czasu tworzenia, planowania architektury i przeróbek to główne czynniki wpływające na ogólny harmonogram projektu. Przeróbki obejmują czynności, takie jak usuwanie usterek projektowych, przepisywanie kodu i naprawianie błędów. Aby znaleźć złoty środek, musimy wziąć pod uwagę zarówno koszty projektu, jak i nieuniknione poprawki wymagane do ukończenia całości systemu.

Architektoniczny złoty środek jest w znacznym stopniu zależny od wielkości, zmienności wymagań i złożoności tworzonego oprogramowania. Wykres na tej stronie na podstawie Boehm’s data [BWO 10] pokazuje, jak zmniejsza się liczba przeróbek, gdy więcej czasu poświęca się na planowanie architektury. Ciągła zielona linia reprezentuje sumę wysiłków włożonych w projekt architektury (niebieska przerywana linia) oraz kosztów przeróbek (przerywana pomarańczowa linia).

W tym przypadku poświęcenie mniej niż około 20% pierwotnego harmonogramu projektu na architekturę będzie skutkować zmniejszeniem korzyści. Mniejsza liczba błędów spowodowana zbyt dużymi inwestycjami w architekturę będzie także powodować wydłużenie całkowitego harmonogramu projektu. I analogicznie – poświęcenie zbyt mało czasu na architekturę spowoduje zwiększenie liczby przeróbek, co również da dłuższy ogólny harmonogram projektu.

W tych samych badaniach Boehm pokazuje również, w jaki sposób zmienia się złoty środek w zależności od szacowanej wielkości systemu oprogramowania. Skorzystajmy z tych danych, aby zdecydować, czy ilość czasu, który planujemy poświęcić na wstępny projekt architektury, znajduje się we właściwym zakresie.

Wykres na stronie 35 zawiera istotne implikacje, przeanalizujmy zatem jego zasadnicze punkty.

Im większy system oprogramowania, tym większe korzyści, jakie uzyskamy dzięki zaprojektowaniu architektury na początku. Z badań przeprowadzonych przez Boehma wynika, że rozsądną decyzją byłoby poświęcenie 37% całkowitego szacunkowego harmonogramu prac na zaprojektowanie architektury dla dużych (10 000 KSLOC, gdzie KSLOC odpowiada tysiącowi źródłowych linii kodu) systemów software’owych.

Mniejsze (10 KSLOC) systemy oprogramowania niewiele zyskują na planowaniu architektury na początku. Z badań Boehma wynika, że zaledwie 5% całkowitego szacunkowego harmonogramu powinno zostać przeznaczone na początkowy projekt architektury. W niektórych przypadkach szybsze może być przepisanie małego oprogramowania niż poświęcenie znacznej ilości czasu na zaprojektowanie architektury z góry.

Możemy porządnie oberwać, jeśli zainwestujemy zbyt mało w projektowanie architektury. Unikanie projektu architektury na początkowym etapie w mniejszych systemach oprogramowania może być bardziej opłacalne i skutkować krótszym ogólnym harmonogramem, ale przeróbki będą nadal konieczne. Przygotujmy się na to i uwzględnijmy w swoich planach gruntowne zmiany projektu. Przy niewystarczających początkowych nakładach na projekt architektury bardziej narażone na to będą większe systemy.

Im więcej zainwestujemy w architekturę, tym mniej przeróbek będzie trzeba dokonać. Planowanie architektury pomaga unikać błędów. Jeśli preferujemy raczej przewidywalne niż efektywne harmonogramy projektów, pomoże nam przeznaczenie większych nakładów na początkowy plan nawet w przypadku mniejszych systemów. Wstępne planowanie jest koniecznością w większych systemach oprogramowania.

Rozmiar to dobry predyktor, ponieważ można go łatwo zmierzyć lub oszacować, ale wiele zespołów stosuje również złożoność [WNA13], aby zdecydować, ile architektonicznej pracy może być wymagane. Duże systemy mogą być złożone, ale nie wszystkie złożone systemy są duże. Jeśli rozwiązanie jest rutynowe, zespołowi może się udać z mniejszymi nakładami planistycznymi, nawet jeśli to duży system.

Kolejnym czynnikiem, który należy wziąć pod uwagę, jest zmienność wymagań. Zmiany w fundamentalnych wymaganiach architektonicznych mogą przekreślić nawet najlepiej stworzone plany. Jeśli spodziewamy się znaczących zmian, opóźnijmy podejmowanie wiążących decyzji i skoncentrujmy się na użyciu mniej obciążających metod projektowania i dokumentowania.

Przypisy

1 https://pragprog.com/book/mkdsa/design-it

2 Grady Booch. Abstracting the Unknown. SATURN 2016. http://resources.sei.cmu.edu/library/asset-view.cfm?assetID=454315