Słowo wstępne
Pamiętam, kiedy Dave i Andy po raz pierwszy ogłosili na Twitterze informację o nowym wydaniu tej książki. To był wielki news. Obserwowałem entuzjastyczną reakcję społeczności programistów. Efekt spełnił oczekiwania. Po dwudziestu latach książka Pragmatyczny programista jest tak samo aktualna, jak jej pierwsze wydanie.
To, że książka z taką historią spotkała się z taką reakcją, jest bardzo znaczące. Miałem przywilej czytania nieopublikowanej kopii po to, by napisać słowo wstępne i zrozumiałem, dlaczego ta publikacja wywołała takie poruszenie. Chociaż jest to książka techniczna, nazywanie jej w taki sposób robi jej niedźwiedzią przysługę. Książki techniczne często odstraszają czytelników. Są wypełnione po brzegi wielkimi słowami, niejasnymi terminami, zawiłymi przykładami. Możesz czuć się zagubiony. Im bardziej doświadczony autor, tym łatwiej jest mu zapomnieć jak to jest, kiedy uczysz się nowych pojęć jako początkujący.
Pomimo dziesięcioleci doświadczeń w programowaniu Dave i Andy podołali trudnemu wyzwaniu pisania z emocjami właściwymi ludziom, którzy dopiero niedawno poznali temat. Nie traktują czytelników "z góry". Nie zakładają, że jesteś ekspertem. Nie zakładają nawet, że czytałeś pierwsze wydanie. Traktują Cię tak jak powinni - jak programistę, który po prostu chce być lepszy. Poświęcili karty tej książki, aby Ci pomóc takim się stać - krok po kroku.
Szczerze mówiąc, zrobili już to wcześniej. Pierwsze wydanie było pełne konkretnych przykładów, nowych pomysłów i praktycznych wskazówek, które budują Twoją "programistyczną muskulaturę" i rozwijają Twój umysł - te przykłady są nadal aktualne. Ale w niniejszej, zaktualizowanej edycji wprowadzono dwa ulepszenia.
Pierwsze jest oczywiste: usunięto niektóre starsze odnośniki, przestarzałe przykłady i zastąpiono je świeżą, nowoczesną zawartością. Nie znajdziesz tu przykładów niezmienników pętli lub maszyn budowania. Dave i Andy zaktualizowali wspaniałą zawartość pierwszego wydania i zadbali o to, aby opisywane zagadnienia były wolne od starych przykładów. Odkurzono w niej stare pomysły, takie jak zasada DRY (don't repeat yourself - dosłownie: nie powtarzaj się) i nałożono na nie świeżą warstwę farby, tak by na nowo zyskały połysk.
Ale to dzięki drugiemu ulepszeniu ta edycja jest naprawdę ekscytująca. Po napisaniu pierwszego wydania autorzy mieli okazję zastanowić się nad tym, co starali się powiedzieć, co chcieli, aby ich czytelnicy wyciągnęli z tej lektury oraz jaki był tego odbiór. Na tej podstawie wyciągnęli właściwe wnioski. Zobaczyli, co nie było najlepiej przekazane, co potrzebowało modyfikacji, jakie treści nie zostały właściwie zrozumiane. W ciągu dwudziestu lat, przez które książka przeszła przez ręce i serca programistów na całym świecie, Dave i Andy studiowali przekazywane im opinie i formułowali nowe pomysły oraz nowe koncepcje.
Nauczyli się znaczenia sprawczości i doszli do przekonania, że programiści mają w sobie większe możliwości sprawcze w porównaniu z większością innych profesjonalistów. Zaczynają tę książkę od prostego, ale głębokiego komunikatu: "To jest Twoje życie". To przypomina o możliwościach tkwiących w naszej bazie kodu, w naszej pracy oraz w naszych karierach. To zdanie ustawia ton dla pozostałej treści tej książki. Przypomina o tym, że jest ona czymś więcej niż tylko kolejną książką techniczną wypełnioną przykładami kodu.
Tym, co naprawdę wyróżnia tę publikację spośród innych książek technicznych jest to, że ta książka pozwala zrozumieć, co to znaczy być programistą. Programowanie to próba doprowadzenia do tego, aby przyszłość stała się mniej uciążliwa. Chodzi w nim o to, aby ułatwiało wykonywanie pracy naszym kolegom. Chodzi o to, aby można było poprawić to, co jest robione źle. O tworzenie dobrych nawyków. O zrozumienie zestawu narzędzi, jakim się posługujemy. Kodowanie to tylko fragment świata programistów. Ta książka ten świat odkrywa.
Poświęciłem dużo czasu na myślenie o mojej "podróży" po krainie kodowania. Nie wyssałem kodowania z mlekiem matki i nie nauczyłem się go na studiach. Nie zajmowałem się zgłębianiem nauk technicznych, kiedy byłem nastolatkiem. Wkroczyłem do świata kodowania kiedy byłem po dwudziestce i musiałem nauczyć się, co to znaczy być programistą. Ta społeczność bardzo różni się od innych, których byłem częścią. Obowiązuje w niej unikatowe poświęcenie się nauce i praktyce; w obu przypadkach jest to zarówno odświeżające, jak i zatrważające.
Dla mnie wejście do społeczności programistów to tak, jakby wejść do nowego świata. Albo przynajmniej zamieszkać w nowym mieście. Musiałem poznać sąsiadów, znaleźć ulubiony sklep spożywczy, dowiedzieć się, gdzie są najlepsze kawiarnie. Poznanie nowego krajobrazu, znalezienie najbardziej efektywnych dróg, aby uniknąć zakorkowanych ulic, poznanie godzin, w których ruch osiąga szczyt, zajęło mi trochę czasu. W nowym mieście pogoda jest inna, więc potrzebowałem nowej szafy.
Pierwsze tygodnie - a nawet miesiące - w nowym mieście mogą być zatrważające. Czy nie byłoby wspaniale mieć przyjaźnie nastawionego, znajomego sąsiada, który mieszka tam już od jakiegoś czasu? Kogoś, kto mógłby zabrać Cię na wycieczkę i pokazać najlepsze kawiarnie? Kto mieszka tam na tyle długo, że zna kulturę, rozumie puls miasta. Dzięki komu mógłbyś nie tylko czuć się tam tak, jak u siebie, ale mógłbyś także stać się aktywnym członkiem społeczności mieszkańców? Dave i Andy są właśnie takimi sąsiadami.
Nowicjusza może łatwo przytłaczać nie sam akt programowania, ale proces stawania się programistą. Musi nastąpić zmiana sposobu myślenia, a także nawyków, zachowań i oczekiwań. Proces stawania się lepszym programistą nie dzieje się dlatego, że wiesz, jak kodować; musisz świadomie dążyć do stosowania dobrych praktyk. Ta książka jest przewodnikiem wiodącym do wydajnego stawania się lepszym programistą.
Niech Cię to jednak nie zmyli - nie znajdziesz tu odpowiedzi na pytanie o to, jakie powinno być programowanie. Ta książka nie pokazuje filozofii programowania, nie przedstawia też tego rodzaju opinii. Powie Ci zaledwie, w prosty i czytelny sposób, kim jest pragmatyczny programista - jak działa oraz jakie stosuje podejście do kodu. Do Ciebie należy decyzja, czy chcesz zostać takim programistą. Jeśli czujesz, że To nie jest dla Ciebie, nikt Cię do niczego nie zmusi. Ale jeśli uznasz, że autorzy tej książki są Twoimi przyjaźnie nastawionymi sąsiadami, to oni pokażą Ci drogę.
Saron Yitbarek
Założyciel i dyrektor wykonawczy firmy CodeNewbie
Gospodarz podcastu "Command Line Heroes"
Przedmowa do drugiego wydania
W latach dziewięćdziesiątych pracowaliśmy z firmami, które miały problemy ze swoimi projektami. Mówiliśmy wszystkim to samo: może powinniście przetestować kod przed opublikowaniem? Dlaczego kod buduje się tylko na maszynie Marii? Dlaczego nikt nie zapytał o zdanie użytkowników?
Aby zaoszczędzić czas spędzony z nowymi klientami, zaczęliśmy robić notatki. Z tych notatek powstała książka Pragmatyczny programista. Ku naszemu zaskoczeniu okazała się strzałem w dziesiątkę. Przez 20 lat od jej wydania nadal jest popularna.
Ale 20 lat to w przypadku oprogramowania wiele życiorysów. Weźcie programistę z roku 1999 i włączcie go do współczesnego zespołu - będzie czuć się nieswojo w tym dziwnym, nowym świecie. Ale świat lat dziewięćdziesiątych jest równie obcy dla dzisiejszych programistów. Odniesienia w książce do takich technologii, jak CORBA, do narzędzi CASE oraz indeksowanych pętli byłyby w najlepszym razie jedynie ciekawostką, a co bardziej prawdopodobne, byłyby mylące.
Jednocześnie trzeba przyznać, że 20 minionych lat nie miało w ogóle wpływu na sposób zdroworozsądkowego myślenia. Być może zmieniła się technologia, ale nie zmienili się ludzie. Praktyki, które były dobre wtedy, pozostają dobre także dziś. Ten aspekt książki dobrze się starzeje.
Kiedy nadszedł czas, aby przygotować niniejsze jubileuszowe wydanie, musieliśmy podjąć decyzję. Mogliśmy przejrzeć książkę i zaktualizować technologie, do których się odwoływaliśmy. Drugim podejściem mogło być ponowne przyjęcie założeń dotyczących zalecanych praktyk w świetle dwóch dekad nowych doświadczeń.
Ostatecznie zrobiliśmy i jedno, i drugie.
W rezultacie ta książka jest czymś w rodzaju statku Tezeusza1. Mniej więcej jedna trzecia tematów w niej jest całkowicie nowa. Większość z reszty została przepisana - częściowo lub całkowicie. Naszym zamiarem było przedstawienie tematów w sposób bardziej czytelny, wyraźniejszy i - mamy nadzieję - bardziej ponadczasowy.
Podjęliśmy kilka trudnych decyzji. Usunęliśmy dodatek "Zasoby", zarówno dlatego, że utrzymanie jego aktualności byłoby niemożliwe, jak i z tego powodu, że łatwiej jest szukać tego, czego potrzebujemy. Zreorganizowaliśmy i przepisaliśmy tematy dotyczące współbieżności. Wzięliśmy przy tym pod uwagę obecną obfitość współbieżnego sprzętu, jak i brak dobrych sposobów jego obsługi. Dodaliśmy treści uwzględniające zmianę postaw i środowisk - począwszy od ruchu Agile, do którego upowszechnienia się przyczyniliśmy, do rosnącej akceptacji idiomów programowania funkcyjnego oraz coraz większej potrzeby uwzględniania aspektów prywatności i bezpieczeństwa.
Co ciekawe, było między nami znacznie mniej dyskusji co do zawartości tego wydania, w porównaniu z pierwszą edycją. Obaj czuliśmy, że łatwiej jest teraz zidentyfikować tematy, które są ważne.
Niniejsza książka jest rezultatem naszej pracy. Życzymy przyjemnej lektury. Być może warto zacząć stosować kilka nowych praktyk. Być może stwierdzicie, że niektóre rzeczy, które proponujemy, są złe. Zachęcamy do zaangażowania się w rozwój naszego rzemiosła. Podzielcie się z nami Waszymi opiniami.
Ale najważniejsze jest to, abyście mieli z tego frajdę.
Jak zorganizowano tę książkę
Ta książka jest zbiorem stosunkowo krótkich podrozdziałów. Każdy podrozdział jest autonomiczny i dotyczy konkretnego zagadnienia. Poszczególne podrozdziały zawierają też liczne odwołania, które znacznie ułatwiają postrzeganie prezentowanych zagadnień w szerszym kontekście. Zachęcamy do swobodnej lektury tych podrozdziałów w dowolnej kolejności - tej książki nie trzeba czytać od pierwszej do ostatniej strony.
Od czasu do czasu można natrafić na ramkę oznaczoną tytułem Wskazówka nr... (na przykład Wskazówka nr 2, "Należy myśleć o tym, co się robi"). Oprócz zwracania szczególnej uwagi na pewne sugestie mamy wrażenie, że wskazówki w tej formie żyją własnym życiem - sami uwzględniamy je w codziennej pracy. Podsumowanie wszystkich wskazówek można znaleźć na wyciąganej karcie na końcu tej książki.
Wszędzie tam, gdzie to było możliwe, proponowaliśmy dodatkowe ćwiczenia i wyzwania. O ile odpowiedzi dla ćwiczeń w większości są stosunkowo proste, wyzwania wymagają głębszego zastanowienia. Aby lepiej zilustrować nasz sposób myślenia, odpowiedzi do ćwiczeń zawarliśmy w dodatku, jednak chcemy podkreślić, że tylko niewielka część tych zadań ma tylko jedno poprawne rozwiązanie. Wyzwania mogą stanowić podstawę dla dyskusji w szerszym gronie lub być tematami rozpraw zadawanych słuchaczom zaawansowanych kursów programowania.
Zamieściliśmy także krótką bibliografię, w której wymieniliśmy książki i artykuły, do których wyraźnie się odwołujemy.
Co to znaczy?
"Kiedy używam jakiegoś słowa - powiedział Humpty Dumpty dość nonszalanckim tonem - oznacza ono tyle, co moim zdaniem ma oznaczać, ani więcej, ani mniej".
Lewis Carroll, Alicja po tamtej stronie lustra
W rozmaitych miejscach tej książki można znaleźć najróżniejsze przykłady żargonu - niektóre z nich są zupełnie prawidłowymi słowami języka polskiego, którym całkiem niedawno nadano jakieś techniczne znaczenie, inne są raczej przerażającymi zlepkami wyrazów wymyślonymi przez informatyków, którzy zdają się nie zważać na piękno swojego języka. Kiedy po raz pierwszy używamy każdego z tych określeń, staramy się je zdefiniować lub przynajmniej dać jakieś wskazówki co do jego znaczenia. Mimo to jesteśmy pewni, że część niejasnych określeń niezauważenie przedostała się przez to sito, a inne, jak "obiekt" czy "relacyjna baza danych", są na tyle popularne, że ich definiowanie byłoby po prostu nudne. W razie napotkania nieznanego terminu w żadnym razie nie należy go ignorować. Warto poświęcić trochę czasu na odnalezienie jego znaczenia, czy to w internecie, czy w innej książce informatycznej. Zachęcamy też do informowania nas o podobnych niedopatrzeniach, tak aby w następnym wydaniu nie zabrakło odpowiednich definicji.
Po tym wstępie możemy przyznać, że postanowiliśmy zrewanżować się informatykom. Istnieją doskonałe określenia stosowane w żargonie informatyków i dobrze opisujące pewne pojęcia czy zjawiska, a mimo to zdecydowaliśmy o ich ignorowaniu. Dlaczego? Ponieważ istniejący żargon zwykle jest kojarzony z konkretną dziedziną problemu lub fazą wytwarzania. Jednym z najważniejszych założeń, które przyświecało nam podczas pisania tej książki, było proponowanie możliwie uniwersalnych technik - na przykład podział na moduły ma zastosowanie w kodzie, projekcie, dokumentacji i organizacji zespołu. Kiedy próbowaliśmy używać typowego słowa żargonowego w szerszym kontekście, nasze intencje stawały się niejasne - nie mogliśmy poradzić sobie z bagażem oryginalnego kontekstu. W każdym takim przypadku postanawialiśmy zwiększyć swój wkład w upadek języka i wymyślaliśmy własne terminy.
Kod źródłowy i inne zasoby
Większość kodu źródłowego prezentowanego w tej książce pochodzi z plików źródłowych gotowych do kompilacji, które są dostępne do pobrania pod adresem:
https://ftp.helion.pl/przyklady/prag2v.zip
Znajdziecie także łącza do zasobów, które uważamy za przydatne, a także aktualizacje książki i wiadomości dotyczące innych przedsięwzięć związanych z książką Pragmatyczny programista.
Prześlij nam opinię
Będziemy wdzięczni za przesyłanie opinii na temat książki. Można wysłać do nas e-mail pod adres redakcja@helion.pl.
Podziękowania do wydania drugiego
W ciągu ostatnich 20 lat przeprowadziliśmy dosłownie tysiące ciekawych rozmów o programowaniu. Spotykaliśmy ludzi na konferencjach, na kursach, a czasami nawet na pokładach samolotów. Każda z tych rozmów poprawiła nasze zrozumienie procesu programowania i przyczyniła się do aktualizacji wprowadzonych w tym wydaniu. Dziękujemy Wam wszystkim (a jeśli jesteśmy w błędzie, dalej mówcie nam o tym).
Dziękujemy uczestnikom procesu beta książki. Wasze pytania i komentarze pomogły nam lepiej wyjaśnić niektóre zagadnienia.
Zanim doszliśmy do wersji beta, udostępniliśmy książkę kilku osobom z prośbą o opinie. Dziękujemy VM (Vicky) Brasseur, Jeffowi Langrowi i Kim Shrier za szczegółowe komentarze, a także José Valimowi i Nickowi Cuthbertowi za opinie techniczne.
Dziękujemy Ronowi Jeffriesowi za pozwolenie skorzystania z przykładu Sudoku.
Jesteśmy wdzięczni pracownikom Wydawnictwa Pearson, którzy zgodzili się, abyśmy stworzyli tę książkę na swój sposób.
Specjalne podziękowania kierujemy dla nieocenionej Janet Furlow, która w mistrzowski sposób kieruje wszystkim, co robi, i która dopilnowała, żebyśmy dotrzymali terminu.
Na koniec dziękujemy wszystkim pragmatycznym programistom, dzięki którym programowanie w ciągu ostatnich dwudziestu lat stało się lepsze dla wszystkich. Mamy nadzieję, że niniejsze wydanie zapoczątkuje kolejne takie dwadzieścia lat.
1 Jeżeli w ciągu wielu lat napraw wadliwych części wymieniono wszystkie oryginalne elementy statku, to czy w dalszym ciągu jest to ten sam statek?
Z przedmowy do pierwszego wydania
Ta książka pomoże czytelnikowi zostać lepszym programistą.
Nie ma znaczenia, czy czytelnik jest wolnym strzelcem, członkiem wielkiego zespołu projektowego, czy konsultantem równocześnie współpracującym z wieloma klientami. Ta książka pomoże każdemu w lepszym wykonywaniu swojej pracy. Ta książka nie jest zbiorem teorii - koncentrujemy się raczej na tematach praktycznych, na efektywnym wykorzystywaniu własnych doświadczeń do podejmowania lepszych decyzji. Słowo pragmatyczny pochodzi od łacińskiego wyrazu pragmaticus ("sprawny w działaniu"), który z kolei pochodzi od greckiego słowa pragmatikós oznaczającego "do zrobienia".
Ta książka jest właśnie o robieniu.
Programowanie jest rzemiosłem. W najprostszej postaci sprowadza się do zmuszania komputera do robienia tego, czego chcemy (lub czego chce użytkownik). Jako programiści jesteśmy po części słuchaczami, po części doradcami, po części tłumaczami i po części dyktatorami. Próbujemy gromadzić ulotne, trudne do sformułowania wymagania i znajdować sposoby ich wyrażania w sposób zrozumiały dla zwykłej maszyny. Staramy się tak dokumentować naszą pracę, aby inni mogli ją zrozumieć, i jednocześnie próbujemy stosować metody inżynierskie, tak aby na bazie naszych dokonań inni mogli budować własne rozwiązania. Co więcej, próbujemy robić to wszystko wbrew bezlitosnym wskazówkom zegara bieżącego projektu. Każdego dnia dokonujemy małych cudów.
To trudna praca.
Wiele osób oferuje nam pomoc. Twórcy narzędzi przekonują o niewiarygodnych możliwościach swoich produktów. Specjaliści od metodyk obiecują, że ich techniki gwarantują doskonałe efekty. Każdy twierdzi, że jego język programowania jest najlepszy i że jego system operacyjny jest pierwszą skuteczną odpowiedzią na wszystkie znane choroby.
Żadne z tych zapewnień oczywiście nie jest prawdziwe. Nie istnieją proste odpowiedzi. Nie istnieje jedno najlepsze rozwiązanie, czy to w formie narzędzia, języka programowania bądź systemu operacyjnego. Mogą co najwyżej istnieć systemy, które w konkretnych okolicznościach sprawdzają się lepiej od konkurencyjnych produktów.
Właśnie tutaj potrzebny jest pragmatyzm. Nie powinniśmy wiązać swojej kariery z żadną konkretną technologią - musimy raczej dbać o stały rozwój swojej wiedzy i gromadzenie doświadczeń niezbędnych do wybierania właściwych rozwiązań w różnych sytuacjach. Nasza wiedza wynika z rozumienia podstawowych zasad informatyki, zaś nasze doświadczenie bierze się z wielu różnych praktycznych projektów. O naszej sile decyduje połączenie teorii i praktyki.
Musimy dostosowywać swoje postępowanie do bieżących okoliczności i środowiska, w którym aktualnie pracujemy. Musimy rozstrzygać względne znaczenie wszystkich czynników wpływających na projekt i wybierać najwłaściwsze rozwiązania na podstawie swoich doświadczeń. Co więcej, musimy robić to nieustannie wraz z postępem prac nad projektem. Pragmatyczni programiści doprowadzają sprawy do końca i robią to dobrze.
Kto powinien przeczytać tę książkę?
Książka jest kierowana do programistów zainteresowanych poprawą swojej efektywności i produktywności. Część programistów jest sfrustrowana wrażeniem niepełnego wykorzystania swojego potencjału. Inni programiści z zazdrością obserwują kolegów po fachu, którzy sprawiają wrażenie, jakby korzystali z narzędzi zapewniających wyższą wydajność. Jeszcze inni używają obecnie starszych technologii i chcą wiedzieć, jak nowe rozwiązania i koncepcje sprawdziłyby się w ich pracy.
Nie udajemy, że znamy wszystkie (ani nawet większość) odpowiedzi. Nie twierdzimy też, że nasze pomysły sprawdzają się we wszystkich sytuacjach. Możemy za to zagwarantować, że postępowanie według naszych zaleceń pozwoli błyskawicznie zdobywać nowe doświadczenia, podniesie produktywność programisty i umożliwi lepsze rozumienie całego procesu wytwarzania. Czytelnik będzie też pisał lepsze oprogramowanie.
Co decyduje o byciu pragmatycznym programistą?
Każdy programista jest inny, ma własne mocne strony i słabości, preferencje i uprzedzenia. Z czasem każdy programista wypracowuje także własne środowisko pracy. Wspomniane środowisko odzwierciedla indywidualne cechy programisty równie mocno jak jego hobby, ubiór czy fryzura. Pragmatyczni programiści mają jednak pewne cechy wspólne (a przynajmniej większość z wymienionych poniżej):
Szybkie sprawdzanie nowinek, błyskawiczne dostosowywanie warsztatu. Pragmatyczni programiści instynktownie poszukują nowych technologii i technik - wprost uwielbiają eksperymentować z nowinkami. Kiedy tylko trafi w ich ręce coś nowego, potrafią błyskawicznie opanować nowe rozwiązania i zintegrować je z resztą swojej wiedzy. Ocena poszczególnych nowości wynika z doświadczenia.
Dociekliwość. Pragmatyczni programiści zadają pytania.
To ciekawe - jak to zrobiłeś? Miałeś jakieś problemy z tą biblioteką? Czym właściwie jest ten BeOS, o którym tyle słyszałem? Jak zaimplementowano dowiązania symboliczne? Pragmatyczny programista jest prawdziwym kolekcjonerem faktów - każda taka informacja może wpłynąć na jego decyzję wiele lat po jej zdobyciu.
Krytyczne myślenie. Pragmatyczni programiści rzadko akceptują otrzymywane informacje bez zapoznania się z faktami. Kiedy nasi koledzy mówią "tak to jest zrobione i już" lub kiedy jakiś producent obiecuje rozwiązanie wszystkich naszych problemów, od razu wiemy, że trzeba to dobrze sprawdzić.
Realizm. Pragmatyczni programiści próbują zrozumieć naturę każdego problemu, z którym muszą się zmierzyć. Realizm pozwala nam dość dobrze szacować trudność poszczególnych zadań i - tym samym - czas trwania planowanych czynności. Świadomość poziomu złożoności procesu i czasu potrzebnego do jego zakończenia pozwala nam wytrwale dążyć do celu.
Gotowość do nowych wyzwań. Pragmatyczni programiści starają się poznawać najróżniejsze technologie i środowiska. Robią, co w ich mocy, aby na bieżąco poznawać nowe technologie i modele wytwarzania. Nawet jeśli aktualny projekt wymaga specjalizacji w określonej dziedzinie, pragmatyczni programiści zawsze są gotowi do pracy w odmiennych obszarach i przyjmowania nowych wyzwań.
Najbardziej podstawowe cechy zostawiliśmy sobie na koniec. Te dwie cechy łączą wszystkich pragmatycznych programistów. Są na tyle proste, że można je wyrazić w formie wskazówek:
Wskazówka nr 1
Należy dbać o swoje rzemiosło.
Uważamy, że tworzenie oprogramowania nie ma najmniejszego sensu, jeśli programista nie dba o jakość swoich produktów.
Wskazówka nr 2
Należy myśleć o tym, co się robi.
Warunkiem bycia pragmatycznym programistą jest ustawiczne myślenie o tym, co się robi, przede wszystkim w trakcie tych czynności. Nie chodzi o jednorazowy audyt bieżących praktyk - powinniśmy raczej krytycznie oceniać każdą podejmowaną decyzję w codziennej pracy i podczas wszystkich czynności związanych z wytwarzaniem. Nigdy nie możemy pozwolić sobie na lot z włączonym autopilotem. Musimy stale myśleć i krytycznie oceniać swoją pracę w czasie rzeczywistym. Stare motto korporacyjne obowiązujące w firmie IBM, MYŚL!, jest też mantrą pragmatycznych programistów.
Jeśli ustawiczne ocenianie własnych decyzji wydaje nam się trudne, możemy być niemal pewni, że spełniamy warunek realizmu. Myślenie rzeczywiście będzie wymagało trochę cennego czasu - czasu, który już teraz jest przedmiotem poważnych nacisków. Nagrodą będzie jeszcze większe zaangażowanie w pracę, którą kochamy, świadomość świetnej znajomości coraz większej liczby zagadnień oraz przyjemne uczucie ciągłego doskonalenia umiejętności. Z czasem zainwestowany czas zwróci się z nawiązką, kiedy my i nasz zespół staniemy się bardziej efektywni, tworzony przez nas kod będzie łatwiejszy w konserwacji, a my sami będziemy tracili dużo mniej czasu na nudnych spotkaniach.
Pojedynczy pragmatycy, wielkie zespoły
Niektórzy sądzą, że w wielkich zespołach lub podczas realizacji złożonych projektów nie ma miejsca na indywidualności. "Tworzenie oprogramowania to zadanie typowo inżynierskie, którego realizacja jest niemożliwa, jeśli poszczególni członkowie zespołu sami podejmują decyzje".
To nieprawda.
Budowa oprogramowania rzeczywiście powinna być przedsięwzięciem inżynierskim. Inżynierski charakter projektu nie wyklucza jednak rzemiosła członków zespołu projektowego. Warto przywołać przykład wielkich katedr budowanych w średniowiecznej Europie. Każda z nich wymagała tysięcy roboczolat, a budowa jednego obiektu nierzadko zajmowała wiele dekad. Lekcje z kolejnych etapów były wykorzystywane przez następne zastępy budowniczych, których osiągnięcia stopniowo przyczyniały się do rozwoju dziedziny mechaniki konstrukcji. Stolarze, kamieniarze, rzeźbiarze i szklarze byli jednak rzemieślnikami, którzy na swój sposób interpretowali wymagania inżynierskie, aby na tej podstawie stworzyć pewną całość - dzieło nieporównanie ciekawsze od czysto mechanicznego aspektu konstrukcji. O sukcesie całych projektów decydowała wiara budowniczych w znaczenie ich indywidualnego wkładu: My, którzy wydobywamy zwykłe kamienie, zawsze musimy mieć przed oczami katedry.
W ramach ogólnej struktury projektu zawsze istnieje przestrzeń dla indywidualności i rzemiosła. Możliwości w tym względzie są szczególnie widoczne na bieżącym etapie rozwoju inżynierii oprogramowania. Nawet jeśli za sto lat nasze współczesne techniki będą wyglądały równie archaicznie co metody stosowane przez średniowiecznych budowniczych katedr w oczach współczesnych inżynierów budownictwa, nasze rzemiosło wciąż będzie doceniane.
To proces bez końca
Turysta zwiedzający angielski Eton College zapytał ogrodnika, jak to możliwe, że trawa jest zawsze tak równo skoszona.
- To proste - odpowiedział - wystarczy lekko podlewać codziennie rano, kosić co drugi dzień i walcować raz w tygodniu.
- To wszystko? - zapytał zdziwiony turysta.
- Oczywiście - odrzekł ogrodnik. - Rób tak przez 500 lat, a też będziesz miał piękny trawnik.
Piękne trawniki wymagają prostych codziennych, choćby niewielkich, nakładów pracy - tak samo jest ze świetnymi programistami. Konsultanci zajmujący się zarządzaniem lubią mówić o ciągłym doskonaleniu (jap. kaizen). Kaizen to japoński termin określający ustawiczne wprowadzanie drobnych udoskonaleń. Uważa się, że właśnie ta filozofia jest jednym z powodów ogromnego wzrostu produktywności i jakości japońskiego przemysłu, stąd jej powszechne powielanie na całym świecie. Filozofia kaizen ma zastosowanie także w przypadku jednostek. Wystarczy codziennie pracować nad doskonaleniem swoich dotychczasowych umiejętności i uzupełniać swój warsztat o nowe narzędzia. Inaczej niż w przypadku trawników w Eton, pierwsze efekty będą widoczne już w ciągu kilku dni. Po latach ze zdziwieniem odkryjemy wprost niewiarygodny wzrost swojego doświadczenia i poprawę umiejętności.
Rozdział 1. Filozofia pragmatyczna
Ta książka jest o Tobie.
Nie popełnij błędu. Tu chodzi o Twoją karierę, a co ważniejsze, to jest Twoje życie . Należy do Ciebie. Czytasz tę książkę, bo wiesz, że możesz stać się lepszym programistą, a także pomagać innym, aby również stali się lepszymi. Możesz stać się pragmatycznym programistą.
Co wyróżnia pragmatycznych programistów? Czujemy, że pragmatyzm to postawa, styl, filozofia postrzegania i rozwiązywania problemów. Pragmatyczni programiści wykraczają myślami poza bieżące, aktualnie rozwiązywane problemy, stale próbując sytuować te problemy w szerszym kontekście, aby dysponować pełnym obrazem analizowanej rzeczywistości. Czy bez świadomości tego szerszego kontekstu w ogóle możemy być pragmatyczni? Jak w takiej sytuacji mielibyśmy wypracowywać inteligentne kompromisy i podejmować świadome decyzje?
Innym kluczem do sukcesu pragmatycznych programistów jest gotowość do brania odpowiedzialności za wszystko, co robią - to zagadnienie zostanie omówione w podrozdziale "Kot zjadł mój kod źródłowy". Odpowiedzialność oznacza, że pragmatyczni programiści nie siedzą bezczynnie, obserwując, jak ich projekty zmierzają ku nieuchronnej klęsce. W podrozdziale "Entropia oprogramowania" zostaną omówione sposoby dbania o nieskazitelność projektów.
Większość ludzi z trudem akceptuje zmiany - niechęć do zmian w pewnych przypadkach jest w pełni uzasadniona, ale nierzadko wynika ze zwykłego marazmu. W podrozdziale "Zupa z kamieni i gotowane żaby" przeanalizujemy strategię inspirowania zmian i przedstawimy (dla równowagi) pouczającą opowieść o płazie, który ignorował niebezpieczeństwa związane ze stopniowymi zmianami.
Jedną z korzyści wynikających ze znajomości i rozumienia kontekstu, w którym pracujemy, jest łatwiejsza ocena tego, na ile dobre musi być tworzone przez nas oprogramowanie. W pewnych przypadkach jedynym akceptowanym stanem jest jakość bliska perfekcji, ale często możliwe są daleko idące kompromisy. Tym zagadnieniem zajmiemy się w podrozdziale "Odpowiednio dobre oprogramowanie".
Zapanowanie nad tym wszystkim wymaga, oczywiście, szerokiej wiedzy i sporego doświadczenia. Uczenie się jest typowym przykładem procesu ciągłego, który nigdy się nie kończy. W podrozdziale "Portfolio wiedzy" omówimy pewne strategie zachowywania właściwego tempa zdobywania wiedzy i umiejętności.
I wreszcie, nikt z nas nie pracuje w próżni. Wszyscy spędzamy znaczną część swojego czasu na interakcji ze współpracownikami. W podrozdziale "Komunikuj się!" zostaną omówione sposoby doskonalenia zasad współpracy.
Programowanie pragmatyczne rozciąga się od filozofii do myślenia pragmatycznego. W tym rozdziale skoncentrujemy się na podstawach filozofii.
1. To jest Twoje życie
Nie żyję w tym świecie, aby sprostać Waszym oczekiwaniom, a Wy nie żyjecie w nim po to, by sprostać moim.
Bruce Lee
To jest Twoje życie. Należy do Ciebie. Ty sam je przeżywasz. Ty sam je tworzysz.
Rozmawiamy z wieloma sfrustrowanymi programistami. Mają różne punkty widzenia. Niektórzy odczuwają, że w ich pracę wkradła się stagnacja, inni - że technologia przeszła obok nich. Ludzie czują się niedostatecznie doceniani albo niedostatecznie opłacani, albo że ich zespoły są toksyczne. Niektórzy chcieliby przenieść się do Azji lub Europy, albo pracować z domu.
Nasza odpowiedź jest zawsze taka sama.
"Dlaczego tego nie zmienisz?".
Wytwarzanie oprogramowania powinno znaleźć się blisko szczytu listy karier, nad którymi masz kontrolę. Nasze umiejętności są poszukiwane, nasza wiedza przekracza granice geograficzne, możemy pracować zdalnie. Jesteśmy dobrze opłacani. Naprawdę możemy zrobić niemal wszystko, czego chcemy.
Ale z jakiegoś powodu programiści są niechętni zmianom. Zamykają się w sobie w nadziei, że sytuacja się poprawi. Biernie godzą się na to, że ich umiejętności stają się przestarzałe i skarżą się, że ich firmy nie wysyłają ich na szkolenia. Jadąc autobusem przyglądają się ogłoszeniom z egzotycznych miejsc, a następnie wychodzą z autobusu na chłód i deszcz i brną do pracy.
Oto najważniejsza wskazówka w tej książce.
Wskazówka nr 3
Masz w sobie możliwości sprawcze.
Denerwuje Cię środowisko, w którym pracujesz? Twoja praca jest nudna? Spróbuj temu zaradzić. Ale nie próbuj w nieskończoność. Jak mówi Martin Fowler: "Można zmienić firmę lub zmienić swoją firmę" 1 .
Jeśli wydaje Ci się, że technologia przechodzi obok Ciebie, znajdź czas (w swoim czasie wolnym) na studiowanie nowych zagadnień, które wydają się interesujące. Inwestujesz w siebie, więc robienie tego w czasie wolnym jest bardzo rozsądne.
Chcesz pracować zdalnie? A czy zapytałeś? Jeśli powiedzą Ci "nie", to znajdź kogoś, kto powie Ci "tak".
Ta branża daje bardzo wiele szans. Bądź proaktywny i z nich skorzystaj.
Pokrewne podrozdziały
Temat 4., "Zupa z kamieni i gotowane żaby". Temat 6., "Portfolio wiedzy".
2. Kot zjadł mój kod źródłowy
Największą słabością jest strach przed wyglądaniem na słabego.
J.B. Bossuet, Politics from Holy Writ , 1709
Jednym z największych elementów filozofii pragmatycznej jest idea brania odpowiedzialności zarówno za siebie, jak i za skutki podejmowanych przez siebie działań (w wymiarze całej kariery, bieżącego projektu i codziennej pracy). Pragmatyczny programista bierze we własne ręce losy swojej kariery i nie boi się przyznać do braku wiedzy czy popełnionego błędu. Przyznawanie się do usterek z pewnością nie jest najprzyjemniejszym aspektem programowania, ale błędy są nieodłączną częścią tej pracy (nawet w najlepszych projektach). Błędy zdarzają się mimo gruntownych testów, dobrej dokumentacji i właściwie zaplanowanej automatyzacji. Dotrzymanie terminu bywa niewykonalne. Programiści napotykają nieprzewidywalne problemy techniczne.
Wspomniane zjawiska po prostu się zdarzają, a rolą programistów jest możliwie profesjonalne radzenie sobie w trudnych sytuacjach. W tym przypadku profesjonalizm wymaga uczciwego i bezpośredniego stawiania sprawy. Mimo dumy ze swoich umiejętności musimy mieć odwagę uczciwego przyznawania się do słabszych stron, w tym braku wiedzy oraz popełnianych błędów.
Zaufanie zespołu
Przede wszystkim Twój zespół musi być w stanie Ci zaufać i na Tobie polegać. Ty także powinieneś móc polegać na każdym członku Twojego zespołu. Według literatury naukowej 2 zaufanie w zespole jest absolutnie niezbędne dla zapewnienia kreatywności i współpracy. W zdrowym, opartym na zaufaniu środowisku, można bezpiecznie mówić to, co się myśli, przedstawiać swoje pomysły i polegać na członkach zespołu, którzy mogą z kolei polegać na Tobie. Co by było, gdyby nie było zaufania? Cóż...
Wyobraźmy sobie, że tajny zespół high-tech ninja pracuje zawzięcie nad infiltracją siedziby złoczyńcy. Po miesiącach planowania i prób uruchamiania kodu wreszcie wszystko jest gotowe. Teraz Twoja kolej, aby skonfigurować siatkę naprowadzania laserowego. Mówisz: "Przepraszam was, ale nie mam lasera. Kot bawił się czerwoną kropką i zostawiłem laser w domu".
Tego rodzaju nadużycie zaufania może być trudne do naprawienia.
Bierz odpowiedzialność
Odpowiedzialność to cecha powszechnie uznawana za pożądaną. Mimo zaangażowania i dbałości o możliwie najlepszą realizację zadania nie zawsze mamy pełną kontrolę nad wszystkimi aspektami naszej pracy. Oprócz jak najlepszego wykonywania własnych działań musimy więc analizować sytuację pod kątem czynników ryzyka wykraczających poza naszą kontrolę. Odrzucenie odpowiedzialności jest usprawiedliwione tylko wtedy, gdy sytuacja uniemożliwia nam prawidłową realizację zadania lub gdy czynniki ryzyka są zbyt poważne. Ocena należy do samego programisty i zależy od jego zasad etycznych i osądu sytuacji.
Jeśli bierzemy na siebie odpowiedzialność za efekt podejmowanych działań, musimy być przygotowani na wszelkie konsekwencje. W razie popełnienia błędu (a wszyscy je popełniamy) lub błędnej oceny sytuacji musimy uczciwie przyznać się do porażki i zaproponować rozwiązanie.
Nie należy winić za własne niedociągnięcia współpracowników ani innych czynników. Nie powinniśmy też szukać usprawiedliwień. Nie należy zrzucać winy za wszystkie problemy na producentów narzędzi, język programowania, przełożonych ani współpracowników. Każdy z tych elementów mógł, oczywiście, przyczynić się do powstałej sytuacji, jednak rolą programisty nie jest szukanie usprawiedliwień, tylko tworzenie rozwiązań.
Jeśli istnieje ryzyko niedostarczenia niezbędnych składników przez kogoś innego, należy przygotować odpowiedni plan awaryjny. Jeśli wskutek awarii dysku programista traci cały kod źródłowy i jeśli nie dysponuje kopią zapasową, wina leży wyłącznie po jego stronie. Problemu nie da się rozwiązać, wmawiając szefowi, że kod źródłowy został zjedzony przez kota.
Wskazówka nr 4
Proponuj rozwiązania, zamiast posługiwać się kiepskimi wymówkami.
Zanim udamy się do kogokolwiek, aby tłumaczyć, dlaczego wykonanie jakiejś czynności jest niemożliwe, dlaczego nie możemy dotrzymać terminu lub dlaczego coś nie spełnia początkowych wymagań, warto zatrzymać się na chwilę i wsłuchać się we własne wyjaśnienia. Warto porozmawiać z gumową kaczką na monitorze, kotem lub czymkolwiek innym. Czy te wyjaśnienia brzmią logicznie, czy po prostu głupio? Jak będą brzmiały dla naszego przełożonego?
Warto przeprowadzić tę rozmowę we własnej głowie. Jakiej odpowiedzi spodziewamy się po rozmówcy? Czy zapyta: "Próbowałeś tego? Nie pomyślałeś o tym"? Jak wtedy odpowiemy? Czy możemy zrobić coś jeszcze, zanim udamy się do przełożonego ze złymi nowinami? W pewnych przypadkach z góry wiadomo, co powie przełożony, zatem warto oszczędzić mu zmartwień.
Zamiast usprawiedliwień należy raczej przygotować propozycje rozwiązań. Nie należy mówić o tym, czego nie można zrobić - powinniśmy raczej koncentrować się na tym, co zrobić, aby wyjść z kłopotliwej sytuacji. Czy porzucenie dotychczasowego kodu rzeczywiście jest konieczne? Warto przedstawić rozmówcy zalety refaktoryzacji (patrz temat 40., "Refaktoryzacja").
Czy planujemy poświęcić czas na przygotowanie prototypu, który ułatwi nam wypracowanie najlepszego rozwiązania (patrz temat 13., "Prototypy i karteczki samoprzylepne")? Czy w przyszłości będzie można uniknąć podobnych sytuacji, jeśli zostaną wdrożone lepsze procedury testowania (patrz temat 41., "Kod łatwy do testowania" i podrozdział "Bezlitosne testy") lub rozwiązania w zakresie automatyzacji.
Być może właściwym rozwiązaniem będzie zapewnienie dodatkowych zasobów. A może trzeba poświęcić więcej czasu użytkownikom? A może wszystko leży w Twoich rękach: być może powinieneś dokładniej nauczyć się jakiejś techniki lub technologii? Może trzeba sięgnąć po książkę lub zapisać się na kurs? Programista nie powinien obawiać się zadawania pytań ani przyznawania do tego, że potrzebuje pomocy.
Warto próbować eliminować kiepskie wymówki jeszcze przed ich głośnym wypowiedzeniem. A jeśli odczuwamy nieodpartą potrzebę ich wyrażenia, przedstawmy te usprawiedliwienia raczej swojemu kotu. Skoro mały Mruczek jest skłonny wziąć winę na siebie, dlaczego nie skorzystać z tej okazji...
Pokrewne podrozdziały
Temat 49., "Pragmatyczne zespoły".
Wyzwania
Jak reagujemy na kiepskie wymówki stosowane przez innych (pracowników banku, mechaników samochodowych, urzędników itp.) podczas rozmowy z nami? Jaki jest wpływ tych wymówek na naszą ocenę rozmówców i organizacji, w których pracują? Gdy kiedykolwiek znajdziesz się w sytuacji, że będziesz zmuszony odpowiedzieć: "Nie wiem", pamiętaj, aby dodać "ale się dowiem". To świetny sposób, aby się przyznać, że czegoś się nie wie, a następnie by przyjąć na siebie odpowiedzialność, tak jak powinien postąpić profesjonalista.
3. Entropia oprogramowania
Chociaż wytwarzanie oprogramowania jest odporne na niemal wszystkie prawa fizyki, akurat zjawisko entropii jest dla programistów aż nadto odczuwalne. Entropia to termin zaczerpnięty z fizyki i opisujący stopień nieokreśloności, chaotyczności w systemie. Prawa termodynamiki mówią, niestety, że entropia we wszechświecie zmierza do osiągnięcia pewnego maksimum. Kiedy zjawisko chaosu zaczyna nasilać się w świecie oprogramowania, mamy do czynienia ze zjawiskiem określanym mianem rozkładu oprogramowania (ang. software rot ). Niektórzy to samo zjawisko określają bardziej optymistycznym terminem "dług techniczny", z domniemanym założeniem, że pewnego dnia go spłacą. Prawdopodobnie im się to nie uda.
Niezależnie od nazwy, zarówno dług techniczny, jak i rozkład oprogramowania, mogą nasilać się w niekontrolowany sposób.
Istnieje wiele czynników, które mogą się składać na rozkład oprogramowania. Bodaj najważniejszym czynnikiem są cechy psychologiczne (lub kulturowe) osób zaangażowanych w realizację projektu. Nawet w przypadku jednoosobowego "zespołu" psychologia projektu może okazać się bardzo delikatna. Nawet najlepsze plany i najlepsi ludzie nie wystarczą do zabezpieczenia projektu przed ruiną i upadkiem w całym czasie życia. Co ciekawe, istnieją projekty, które wbrew licznym utrudnieniom i mimo pasma niepowodzeń zadziwiająco skutecznie radzą sobie z naturalnym dążeniem do nieporządku i doskonale znoszą upływ czasu.
Co decyduje o tej różnicy?
W centrach miast tylko część budynków jest pięknych i zadbanych, podczas gdy pozostałe to rozpadające się rudery. Dlaczego? Badacze zjawiska przestępczości i degradacji życia społecznego w miastach odkryli bardzo ciekawy mechanizm, który może sprawić, że czysty, zadbany, zamieszkany budynek błyskawicznie pustoszeje i zaczyna niszczeć 3 .
Wystarczy jedna wybita szyba.
Jedna wybita szyba pozostawiona nienaprawiona przez dłuższy czas powoduje, że mieszkańcy zaczynają traktować swój dom jako opuszczone, porzucone miejsce, które nie może liczyć na właściwą opiekę wyznaczonych do tego podmiotów. Niedługo potem zostaje zbita kolejna szyba. Ludzie zaczynają pozostawiać śmieci w przypadkowych miejscach. Na murach pojawia się graffiti. Po jakimś czasie budynek jest już narażony na poważne uszkodzenia strukturalne. W stosunkowo krótkim okresie budynek znajduje się w stanie, w którym przywrócenie dawnej świetności traci sens ekonomiczny, zatem pierwotne wrażenie porzucenia staje się rzeczywistością.
Dlaczego ta jedna wybita szyba stwarza tak wielką różnicę? Z badań psychologów 4 wynika, że pokazanie stanu beznadziejności może być zaraźliwe. Weźmy za przykład rozprzestrzenianie się wirusa grypy w dużych skupiskach ludzkich. Ignorowanie wyraźnie nieprawidłowej sytuacji wzmacnia pogląd, że prawdopodobnie nic nie można naprawić, że nikogo to nie interesuje, wszystko jest przesądzone. Pojawiają się negatywne myśli, które mogą rozprzestrzeniać się między członkami zespołu, tworząc błędne koło.
Wskazówka nr 5
Nie akceptuj żadnej wybitej szyby.
Nie należy pozostawiać nienaprawionej żadnej wybitej szyby (złego projektu, niewłaściwej decyzji, kiepskiego kodu itp.). Każdą taką "szybę" należy wymienić zaraz po odkryciu problemu. Jeśli brakuje czasu na wstawienie nowej szyby, należy wstawić w jej miejsce choćby dyktę . W większości przypadków można sobie pozwolić na umieszczenie problematycznego kodu w komentarzu, wyświetlenie komunikatu "Do zaimplementowania" lub celowe wstawienie błędnych danych, które na pewno zwrócą uwagę programistów. Należy też podjąć działania nie tylko na rzecz ograniczenia ryzyka wywołania dalszych szkód przez wykrytą usterkę, ale też w celu dowiedzenia, że panujemy nad sytuacją.
Każdy z nas widział piękne, w pełni funkcjonalne systemy, które rozsypywały się jak domek z kart, kiedy tylko pojawiły się "wybite szyby". Istnieją też inne czynniki prowadzące do rozkładu oprogramowania (wrócimy do nich w dalszej części tej książki), ale nic tak nie przyspiesza tego zjawiska jak zaniedbania.
Część programistów sądzi, że konsekwentne sprzątanie rozbitego szkła i wstawianie nowych szyb jest niewykonalne - że nikt nie ma na to czasu podczas realizacji projektu. Programiści, którzy podzielają ten pogląd, powinni albo zaopatrzyć się w duży kubeł na śmieci, albo zmienić sąsiedztwo. Nie pozwólmy entropii wygrać.
Po pierwsze nie szkodzić
Andy miał kiedyś znajomego, który był nieprzyzwoicie bogaty. Jego dom był pełen bezcennych antyków, dzieł sztuki itp. Pewnego dnia zapalił się gobelin zawieszony zbyt blisko kominka w salonie. Wezwano na pomoc straż pożarną, aby zapobiec katastrofie. Mimo szalejącego pożaru strażacy poprzedzili rozwinięcie swoich wielkich, brudnych węży starannym rozłożeniem mat pomiędzy drzwiami wejściowymi a źródłem ognia.
W ten sposób zabezpieczyli dywan przed niepotrzebnym zabrudzeniem.
Opisany scenariusz z pewnością jest mocno przesadzony. Zapewne najważniejszym priorytetem straży pożarnej powinno być ugaszenie pożaru, bez względu na inne szkody. Jednak straż pożarna najwyraźniej właściwie oceniła sytuację. Strażacy byli przekonani o zdolności do zapanowania nad ogniem i zastosowali środki ostrożności w celu uniknięcia niepotrzebnych zniszczeń w budynku. W podobny sposób należy postępować z oprogramowaniem: nie należy powodować dodatkowych szkód tylko dlatego, że powstał jakiś kryzys. Jedna wybita szyba to o jedna za dużo.
Jedna wybita szyba (źle zaprojektowany fragment kodu, błędna decyzja kierownictwa utrudniająca pracę zespołu w całym okresie realizacji projektu itp.) w zupełności wystarczy do rozpoczęcia procesu degradacji. Programista zaangażowany w projekt, w którym aż roi się od takich "wybitych szyb", nie może pogodzić się z sytuacją i przyjąć postawy: "Skoro cała reszta kodu nadaje się do kosza, po co mój kod miałby się czymś wyróżniać?". Jakość projektu do momentu, w którym trafia do rąk programisty, nie powinna mieć żadnego znaczenia. W oryginalnym projekcie, który doprowadził do powstania teorii wybitej szyby, porzucony samochód początkowo stał nietknięty przez tydzień. Wystarczyło jednak wybicie jednej szyby, aby w ciągu zaledwie paru godzin samochód został rozebrany niemal do gołej karoserii.
Podobnie, programista dołączający do zespołu realizującego projekt, którego kod jest przykładem nieskazitelnego piękna (jest wyjątkowo przejrzysty, doskonale zaprojektowany i elegancki), najprawdopodobniej będzie robił wszystko, aby niczego nie zepsuć (jak strażacy w przytoczonej anegdocie). Nawet w warunkach szalejącego pożaru (zbliżającego się terminu, nadchodzącej daty wydania, planowanej prezentacji itp.) nikt nie chce być pierwszą osobą, która zakłóci dotychczasową harmonię.
Po prostu sobie powiedz: "nie ma przyzwolenia na wybite szyby".
Pokrewne podrozdziały
Temat 10., "Ortogonalność". Temat 40., "Refaktoryzacja". Temat 44., "Nazewnictwo".
Wyzwania
Warto pomóc we wzmocnieniu swojego zespołu poprzez dokonanie gruntownego przeglądu otoczenia, w którym pracuje. Należy wybrać dwie lub trzy "wybite szyby", po czym omówić ze współpracownikami źródła poszczególnych problemów i możliwe rozwiązania. Czy potrafimy wskazać szybę, która została wybita jako pierwsza? Jaka była nasza reakcja po jej pierwszym wykryciu? Jeśli ta "wybita szyba" wynika z decyzji kogoś innego lub polecenia kierownictwa, jak możemy temu zaradzić?
4. Zupa z kamieni i gotowane żaby
Trzej głodni żołnierze wracali z wojny. Kiedy zobaczyli na swojej drodze wioskę , byli pełni nadziei - byli przekonani, że mieszkańcy osady zaproszą ich na posiłek. Po dotarciu na miejsce odkryli jednak, że wszystkie drzwi i okna są pozamykane. Po wieloletniej wojnie mieszkańcy wsi dysponowali niewielką ilością jedzenia i pilnie strzegli swoich zapasów.
Zdeterminowani żołnierze zagotowali kocioł wody i ostrożnie włożyli do wrzątku trzy kamienie. Zaskoczeni wieśniacy zaczęli wychodzić ze swoich domów i obserwować poczynania żołnierzy.
- To jest zupa z kamieni - wyjaśnili żołnierze.
- To wszystko, co do niej włożycie? - dopytywali mieszkańcy osady.
- Oczywiście, chociaż są tacy, którzy twierdzą, że zupa jest jeszcze lepsza z kilkoma marchewkami. - Jeden z wieśniaków natychmiast pobiegł do swojego domu, by po chwili przynieść kosz pełen marchwi.
Kilka minut później wieśniacy znowu zaczęli dopytywać:
- To naprawdę wszystko?
- Cóż - odpowiedzieli żołnierze - kilka ziemniaków na pewno by nie zaszkodziło . - Po chwili inny wieśniak przybiegł z workiem ziemniaków.
Po godzinie żołnierze dysponowali składnikami, które w zupełności wystarczyły do przyrządzenia wymarzonej zupy: wołowiną, porem, solą i ziołami. Za każdym razem inny mieszkaniec wsi plądrował własną spiżarnię w poszukiwaniu składnika wskazanego przez żołnierzy.
Ostatecznie udało się ugotować całkiem spory kocioł doskonałej zupy. Żołnierze wyjęli z zupy kamienie, po czym usiedli wraz z mieszkańcami wsi, aby wspólnie celebrować pierwszy pełnowartościowy posiłek od wielu miesięcy.
Z historii o zupie z kamieni płynie wiele wniosków. Wieśniacy zostali oszukani przez żołnierzy, którzy wykorzystali ich ciekawość do zdobycia niezbędnych składników. Ważniejsze jest jednak coś zupełnie innego - żołnierze zadziałali jak katalizator skupiający społeczność wokół jednego celu i umożliwiający ugotowanie posiłku, którego poszczególni mieszkańcy wsi nie mogliby sporządzić na bazie własnych zapasów. Mamy więc do czynienia z pożądanym skutkiem synergii. Ostatecznie wszyscy odnieśli korzyści.
Warto więc spróbować zastosować metodę tych żołnierzy we własnym środowisku.
Możemy znaleźć się w sytuacji, w której doskonale wiemy, co należy zrobić i jak to osiągnąć. Wyobraźmy sobie, że mamy w głowie kompletną koncepcję systemu, o której z całą pewnością wiemy, że jest słuszna. Przyjmijmy jednak, że musimy uzyskać zgodę na to przedsięwzięcie i że spotykamy się z niechęcią i brakiem zrozumienia. Musimy przekonać rozmaite komitety, zadbać o akceptację zaproponowanego budżetu - projekt już na tym etapie bardzo się komplikuje. Każdy zazdrośnie strzeże swoich zasobów. Opisane zjawisko bywa określane mianem próby sił na początku działalności (ang. start-up fatigue ).
To dobry moment, by sięgnąć po kamienie. Należy dobrze przemyśleć, o które składniki warto prosić. Warto dobrze wykorzystać każdy otrzymany składnik. Po otrzymaniu półproduktu należy zaprezentować efekt wszystkim zainteresowanym i pozwolić, by zachwycali się otrzymanym dziełem. Kiedy powiedzą: " byłoby jeszcze lepsze, gdyby dodać...", można udawać, że proponowane ulepszenia są nieistotne. Wystarczy teraz rozsiąść się wygodnie i czekać, aż sami zaczną sugerować dodawanie funkcji, które od początku chcieliśmy zaimplementować w tym systemie. Wielu ludziom łatwiej przychodzi dołączanie do udanego projektu niż praca na niepewny sukces od podstaw. Warto więc tak opisać perspektywy projektu, aby byli przekonani o jego świetlanej przyszłości 5 .
Wskazówka nr 6
Bądź katalizatorem zmian.
Mieszkańcy wsi
Jeśli spojrzymy na historię zupy z kamieni z punktu widzenia wieśniaków, otrzymamy opowieść o subtelnym i postępującym oszustwie. To historia o zbyt wąskiej perspektywie. Mieszkańcy osady są tak zaintrygowani kamieniami, że zapominają o bożym świecie. To samo zdarza się każdemu, codziennie. Pewne rzeczy potrafią zadziwiająco skutecznie przykuwać naszą uwagę.
Opisane symptomy są nam doskonale znane. Projekty powoli, ale nieuchronnie wymykają nam się z rąk. Większość katastrof w świecie oprogramowania rozpoczyna się od zjawisk tak niepozornych, że wręcz trudnych do dostrzeżenia. Co więcej, większość projektów nie jest realizowana w terminie. Systemy oddalają się od swoich oryginalnych specyfikacji funkcja po funkcji. Co więcej, kolejne łatki eliminujące usterki powodują, że z czasem produkt nie ma nic wspólnego z oryginałem. Na spadek morale i rozpad zespołu często składa się wiele drobnych zjawisk, tyle że kumulowanych w dłuższym okresie.
Wskazówka nr 7
Pamiętaj o szerszym kontekście.
Nigdy tego nie próbowaliśmy. Naprawdę. Mówi się, że żywa żaba wrzucona do gotującej się wody natychmiast wyskoczy z garnka. Jeśli jednak wrzucimy żabę do zimnej wody i zaczniemy tę wodę stopniowo nagrzewać, żaba nie zwróci uwagi na powolny wzrost temperatury i pozostanie w garnku, aż zostanie ugotowana.
Łatwo zauważyć, że w przypadku żaby mamy do czynienia z zupełnie innym problemem od tego, który omówiono we wcześniejszym podrozdziale na przykładzie zbitej szyby. Zgodnie z teorią wybitej szyby ludzie tracą zainteresowanie walką z entropią, kiedy odkrywają, że byliby w tej walce osamotnieni - że otaczająca ich społeczność bagatelizuje problem. Żaba nawet nie dostrzega zmiany.
Nie możemy upodabniać się do tej żaby. Musimy mieć na uwadze szerszy obraz sytuacji. Powinniśmy stale obserwować to, co dzieje się w otaczającym nas świecie, zamiast koncentrować się tylko na swoich zadaniach.
Pokrewne podrozdziały
Temat 1., "To jest Twoje życie". Temat 38., "Programowanie przez koincydencję".
Wyzwania
Podczas recenzowania wstępnej wersji tej książki John Lakos zwrócił uwagę na ciekawe zjawisko. Żołnierze stopniowo oszukiwali mieszkańców wioski, ale powodowana przez to oszustwo zmiana postawy wieśniaków była dla wszystkich korzystna. Stopniowe oszukiwanie żaby ostatecznie prowadzi do jej skrzywdzenia. Czy potrafimy stwierdzić, kiedy przyspieszanie zmian odbywa się metodą zupy z kamieni, a kiedy zupy z żaby? Czy ta ocena będzie subiektywna, czy obiektywna? Odpowiedz szybko, bez spoglądania, ile lamp jest na suficie nad Tobą? Ile jest ich wszystkich w pokoju? Ile osób w nim przebywa? Czy jest coś spoza kontekstu - coś, co wygląda jakby nie należało do wystroju? Jest to ćwiczenie na
świadomość sytuacyjną - technikę praktykowaną zarówno przez skautów, jak i oddziały marynarki wojennej Stanów Zjednoczonych. Nabierz nawyku obserwowania otoczenia i spostrzegania tego, co się w nim znajduje. Następnie stosuj ten sam nawyk w swoim projekcie.
5. Odpowiednio dobre oprogramowanie
Kto lepsze goni, często w gorsze wpadnie.
Król Lear , akt I, scena IV
Istnieje stary dowcip o amerykańskiej firmie, która zamówiła 100 tysięcy układów scalonych u japońskiego producenta. Specyfikacja zawierała błąd, który powodował usterkę w jednym na 10 tysięcy układów. Kilka tygodni po złożeniu zamówienia do firmy dotarło wielkie pudło z tysiącami układów scalonych oraz małe pudełko z zaledwie dziesięcioma układami. W pudełku znajdowała się kartka z napisem: "Tutaj są te układy z błędami".
Opinie na temat drugiego wydania książki Pragmatyczny programista
Niektórzy twierdzą, że w książce Pragmatyczny programista Andy i Dave schwytali błyskawicę do butelki. Jest mało prawdopodobne, aby ktoś wkrótce napisał książkę, która poruszy branżę w taki sposób, w jaki oni to zrobili. Czasami jednak błyskawica uderza dwa razy. Ta książka jest dowodem, że to możliwe. Dzięki zaktualizowanej treści pozostanie ona na szczycie list najlepszych publikacji dotyczących rozwoju oprogramowania przez 20 kolejnych lat. To miejsce jej się należy.
VM (Vicky) Brasseur
Dyrektor strategii open source, Juniper Networks
Jeśli chcesz, aby Twoje oprogramowanie było łatwe do aktualizacji i utrzymania, miej pod ręką egzemplarz książki Pragmatyczny programista. Jest ona pełna praktycznych porad, zarówno technicznych, jak i zawodowych, które będą służyły Tobie i Twoim projektom przez długie lata.
Andrea Goulet
Dyrektor naczelny firmy Corgibytes; założyciel witryny LegacyCode.Rocks
Pragmatyczny programista to książka, która całkowicie zmieniła tor mojej kariery w tworzeniu oprogramowania i wskazała kierunek do sukcesu. Jej lektura otworzyła mój umysł na możliwości bycia rzemieślnikiem, a nie tylko trybikiem w wielkiej maszynie. To jedna z najważniejszych książek w moim życiu.
Obie Fernandez
Autor książki The Rails Way
Czytelnicy, którzy sięgają po tę książkę po raz pierwszy, mogą spodziewać się fascynującego wprowadzenia do nowoczesnego świata praktyk tworzenia oprogramowania - świata, w którego kształtowaniu pierwsze wydanie tej książki odegrało ważną rolę. Czytelnicy pierwszej edycji na nowo odkryją trafne spostrzeżenia i praktyczną mądrość, dzięki którym ta publikacja stała się tak ważna. Drugie wydanie zostało fachowo uzupełnione i uaktualnione dużą ilością nowego materiału.
David A. Black
Autor książki The Well-Grounded Rubyist
Mam na półce starą, papierową kopię pierwszego wydania Pragmatycznego programisty. Książkę tę czytałem wiele razy i stale do niej wracam. Dawno temu zmieniła ona wszystko w sposobie, w jaki podchodziłem do zawodu programisty. W nowym wydaniu zmieniło się wszystko, a jednocześnie nie zmieniło się nic: teraz czytam ją na moim iPadzie, a w przykładach kodu wykorzystano nowoczesne języki programowania, ale opisywane pojęcia, pomysły i sposoby postępowania są ponadczasowe i mają uniwersalne zastosowanie. Dwadzieścia lat po pierwszym wydaniu książka jest tak samo aktualna, jak kiedyś. Jestem szczęśliwy, że obecni i przyszli programiści będą mieć taką samą okazję uczenia się od Andy'ego i Dave'a ich głębokich spostrzeżeń, jaką miałem ja czytając pierwsze wydanie.
Sandy Mamoli
Trener Agile, autor książki How Self-Selection Lets People Excel
Dwadzieścia lat temu pierwsze wydanie Praktycznego programisty całkowicie zmieniło trajektorię mojej kariery. Niniejsza nowa edycja może zrobić to samo dla Was.
Mike Cohn
Autor książek Succeeding with Agile, Agile Estimating and Planning oraz User Stories Applied