Sposób, który wygląda na idealne rozwiązanie problemu programującego durnia. Zaplanować, opisać, udokumentować, przeszkolić. Analizę robimy tak, projekt techniczny siak, kod piszemy owak, testy według formalnego planu w iluś tam etapach, release według checklisty. Wszędzie oczywiście szczegółowe zalecenia - od spisu dokumentów i raportów po 9432 szczegółowe zalecenia co do formy kodu.
Będzie wiadomo co i jak trzeba robić, to każdy będzie mógł te operacje wykonywać.
Wspomnienie sprzed lat
To był drugi czy może trzeci rok mojej pracy zawodowej. Trafiłem na kurs zarządzania projektami według metodyki LBMS, niedługo potem otarłem się o serię prezentacji i pokazów narzędzi CASE (wówczas sprzedawanych jako narzędzia do zarządzania całym procesem produkcji oprogramowania), do tego przeczytałem parę książek (Yourdon, Booch, Rumbough, Shlaer-Mellor, ...).
Pamiętam, jak wielkie wrażenie robiła na mnie wtedy perspektywa logicznie uporządkowanego projektu, w którym dokładnie wiadomo jaki dokument (i według jakiego szablonu) w którym momencie napisać, jaki diagram którego dnia namalować, jakie role są potrzebne, co z czego wynika, kiedy komu co zaraportować itd. Tylko kupić książkę i narzędzia, jechać według planu i nawet najtrudniejszy software się deterministycznie urodzi w zadanym czasie a use-case bezpośrednio doprowadzi mnie do kodu, architektury sprzętowej i szczegółowego planu testów. Ustawić dobry proces a reszta zrobi się sama.
Życie dokonało tu szybkiej a brutalnej weryfikacji, wystarczyło kilka lat, by większość z tych firm po prostu znikła, a narzędzia CASE zaczęły być postrzegane dużo bardziej realistycznie - jako wsparcie dla dokumentowania projektu i forma komunikacji między programistami.
Miałem też trochę własnych doświadczeń. Malowanie szczegółowych obrazków okazało się bardzo pracochłonne a tak naprawdę niewiele wnoszące, dokumenty pisane pod szablon faktycznie trochę łatwiej się pisało ale dużo ciężej czytało, round-trip engineering (czyli płynne przechodzenie między modelem a kodem w obie strony) okazał się całkowitym mitem, a trudne decyzje dotyczące architektury czy algorytmów trudnymi pozostały.
Dziś wiara w narzędzia CASE przeminęła ale sam mit formalnego, ściśle zorganizowanego procesu w coraz to innych inkarnacjach powraca.
Uważam za szczególnie atrakcyjny paradoks spotykaną gdzieniegdzie ślepą wiarę w rozmaite procesy Agile - oczekiwanie, że ich ścisłe przestrzeganie automatycznie zapewni sukces niezależnie od tego kto i do czego będzie je wykorzystywał. Paradoks, bo u podstaw Agile leży kładzenie nacisku na ludzi a nie proces oraz akceptowanie niepewności i zmian. Jeśli to odrzucimy, to nawet z daily scrum możemy zrobić odgrywany rytuał.
Algorytm programisty
W wielu dyskusjach i tekstach na temat organizowania pracy węszę pokusę napisania algorytmu działania programisty. Tak precyzyjnie opisać prace i czynności, by ludzie automatycznie kroczyli wyznaczoną ścieżką nie ryzykując żadnego fałszywego kroku. Z zasady im dalej konstruująca procesy osoba jest od kodowania, tym większe ma tego typu nadzieje.
Na samym dole, przy kodzie, w trakcie realizacji zadania - widać, że to ułuda.
Jakkolwiek pięknie, logicznie i precyzyjnie wygląda proces, w końcu zawsze jest programista, klawiatura i puste okno edytora, które trzeba wypełnić treścią. I to programista musi rozstrzygnąć wątpliwości, zauważyć zagrożenia, skorzystać z szans reużywania kodu, ...
Podobnie - jak precyzyjnie nie byłaby opisana metoda diagnozowania i usuwania błędów, w końcu rozbija się o doświadczenie, wnikliwość, intuicję i wiedzę osoby zajmującej się problemem.
Zdarzają się czynności prawdziwie rutynowe. Tylko ... zamiast zastanawiać się nad ich formalizowaniem lepiej zająć się automatyzacją.
Biurokracja
Naturalną konsekwencją przesadnej wiary w proces jest biurokracja.
Najpierw zasady robią się coraz bardziej skomplikowane. Gdzieś, ktoś,
coś zrobi niewłaściwie albo o czymś zapomni? Uzupełniamy procedurę!
Funkcja main
musi kończyć się return 0
, każda klasa ma mieć
wirtualny destruktor, używamy tylko VARCHAR
a nie CHAR
,
dokumentacja konfiguracji zawierać przynajmniej dwa zdania na temat
każdego z parametrów, w raporcie błędu trzeba koniecznie załączyć
logi, buildu nie można wypuścić jeśli jakikolwiek test nie przeszedł,
coverage musi wskazywać co najmniej 90%, pliki powyżej dwustu wierszy
należy podzielić na mniejsze, używamy tylko sprytnych wskaźników, ...
Potem, skoro zasad jest dużo, coraz trudniej o nich pamiętać. Dlatego pojawiają się raporty. Audyt kodu na zgodność z szablonem. Szczegółowa specyfikacja testów developerskich akceptowana przez kierownika. Raport przebiegu buildu. Formalne sprawozdanie z działań przy szukaniu błędu.
Co ciekawe, wszystko to najczęściej koncentruje się na rzeczach trywialnych a niebanalne pomija. Dyskusje na temat długości wiersza kodu, niewłaściwego nazewnictwa zmiennych albo długości pliku są wszechobecne, architektura systemu formalizmom umyka.
Nie rób drugiemu co tobie niemiłe
W definiowaniu procesów jest łatwa pokusa, by zwiększać wymagania w stosunku do innych, nakładać im dodatkowe obowiązki, potem oceniać. Reality check następuje jeśli autor wymagań spróbuje zastosować je do siebie.
To są zwykle łatwe pytania.
Czy mam coś przeciw kompilacji z aktywnymi warningami i korygowaniu kodu, by nie występowały? Raczej nie. Czy chciałbym przy pisaniu każdej klasy sprawdzać trzystupunktowy style-guide? Hmm...
Przeszkadza mi fakt, że narzędzie zarządzania wersjami zachowuje informację co i kiedy zmieniłem? Skądże. Przeszkadzałaby konieczność każdorazowego uzyskiwania zgody kierownika na wprowadzenie zmian? Owszem.
Czy chciałbym sobie nawzajem przeglądać aktualnie pisany kod z kolegą z sąsiedniego pokoju? Czemu nie, chętnie. Czy chciałbym, by ktoś analizował to co pisałem przez ostatnie pół roku i raportował listę uchybień do szefa bez mojej wiedzy? Niekoniecznie.
Itd, itp.
Przewidywalność
Trafiłem niedawno na ten artykuł Toma de Marco. Autor legendarnej maksymy You can't control what you can't measure, wybitny specjalista od zarządzania projektami informatycznymi, teraz pisze między innymi:
I’m gradually coming to the conclusion that software engineering is an idea whose time has come and gone. I still believe it makes excellent sense to engineer software. But that isn’t exactly what software engineering has come to mean. The term encompasses a specific set of disciplines including defined process, inspections and walkthroughs, requirements engineering, traceability matrices, metrics, precise quality control, rigorous planning and tracking, and coding and documentation standards. All these strive for consistency and predictability.
Consistency and predictability are still desirable, but they haven’t ever been the most important things. For the past 40 years, for example, we’ve tortured ourselves over our inability to finish a software project on time and on budget. But as I hinted earlier, this never should have been the supreme goal. The more important goal is transformation, creating software that changes the world or that transforms a company or how it does business. (...) Software development is and always will be somewhat experimental. The actual software construction isn’t necessarily experimental, but its conception is. And this is where our focus ought to be. It’s where our focus always ought to have been.
czyli
Dochodzę do wniosku, że czas inżynierii oprogramowania się kończy. Nadal wierzę, że tworzenie oprogramowania ma głęboki sens. Ale nie o to chodziło w inżynierii programowania. Ten termin oznacza specyficzny zbiór zasad obejmujących zdefiniowany proces, audyty i przeglądy, zarządzanie wymaganiami, metryki, kontrolę jakości, rygorystyczne planowanie i nadzór, standardy kodu i dokumentacji. Wszystko to ukierunkowane jest na powtarzalność i przewidywalność.
Powtarzalność i przewidywalność są pożądane ale nigdy nie były najważniejszymi sprawami. Przez 40 lat zadręczaliśmy się naszą niezdolnością kończenia prac na czas i w ramach budżetu. Ale to nigdy nie powinien być podstawowy cel. Ważniejsza jest transformacja, tworzenie kodu który zmieni świat albo, przynajmniej, zmieni firmę i sposób w jaki robi ona biznes. (...) Informatyka zawsze była w jakiejś mierze dziedziną eksperymentalną - jeśli nawet nie przy samej konstrukcji kodu, to przy opracowywaniu jego koncepcji. A to na tym powinniśmy się skupiać. Na tym zawsze powinniśmy się byli skupiać.
Procesy są potrzebne
Aby nie pójść z wnioskami zbyt daleko: procesy i zasady są przydatne. Niektóre - jak zarządzanie wersjami, rejestracja błędów, ustalanie priorytetów prac, tryby przygotowania dystrybucji, support produkcyjny - niezbędne.
Ale to jest tylko narzędzie.
Nie wyobrażam sobie jazdy samochodem bez kodeksu drogowego i znaków. Panowałby chaos. Niemniej jednak, kluczowe dla bezpiecznej i efektywnej jazdy jest to, co ja zrobię za kółkiem.
Dokładnie tak samo patrzę na procesy organizacyjne i programowanie. Procesy dają niezbędne podstawy. Ale kluczowe jest to, co dzieje się poza nimi, co robią ludzie.
Walka o prostotę
Tak jak kodeks drogowy musi być cienki i łatwy do zapamiętania, a dobrze rozmieszczone znaki stoją rzadko, tak proces powinien być mały. Bardzo stary cytat z książki Boocha i Martina (tak, tego Grady Boocha):
A process that is too complex will fail. Simplicity is a value to be intensely defended, both in our software, and in our process. We will not add activities or artifacts to our processes unless the need for them is critical. We will regularly sweep through our processes and remove accumulated complexity. Anything that cannot be completely justified, is eliminated. A process description should always look too small.
czyli
Proces, który jest zbyt skomplikowany, nie powiedzie się. Prostota jest wartością której musimy zdecydowanie bronić, zarówno w naszym oprogramowaniu, jak w naszych procesach. Nie powinniśmy dodawać czynności ani produktów do naszych procesów o ile nie są krytycznie potrzebne. Wszystko, czego nie da się całkowicie uzasadnić, trzeba wyeliminować. Opis procesu zawsze powinien wydawać się zbyt krótki.