Béton brut

Problem z dzięciołem

2012-07-31

Gdyby architekci stawiali budynki tak, jak programiści piszą programy, to jeden dzięcioł rozwaliłby całą naszą cywilizację

„Piękny budynek. Doskonały. Te kształty, basen przy ogródku. Podoba mi się. Naprawdę mi się podoba. Niestety, wnuczek jednej z pań powiedział nam, że w tym sezonie sensowniej byłoby zbudować igloo i martwić się letnimi problemami w lecie. Za ile możemy mieć igloo? Nie znam się na architekturze, ale wygląda mi to na kilka dni roboty.”

Rozmawiałem ostatnio z kilkoma inżynierami. A raczej słuchałem, jak odmieniali cytat z góry przez różne przypadki. Własne przypadki przeżyć podczas używania bardzo złego oprogramowania. Potakiwałem. Nie oszukujmy się, jest cała masa przykładów usprawiedliwiających ich drwiny. Sam, częściej niż bym chciał, produkuję kod, którego jakość można zakwestionować. Nie będąc wtedy w stanie wymyślić jakiejś sensownej linii obrony własnej pracy, zapisałem sobie w notatniku, żeby zmierzyć się z tym problemem w wolnym czasie.

Nie mam niestety wolnego czasu, więc spróbuję podumać „na głos” dziś.

Pierwszym problemem w porównaniu pracy programisty z pracą inżyniera jest końcowy efekt. Życie aplikacji, choć zwykle krótsze niż w przypadku budynku, mostu czy nowego modelu silnika, nie ma końca. Oczywiście pojawiają się nowe, stabilne wersje, ale programista jest zmuszony ciągle odgadywać przyszłe intencje klienta czy też użytkowników. Czasem jedna decyzja technologiczna podjęta w wersji n może okazać się niesamowitym źródłem problemów podczas dopisywania nowej funkcjonalności w wersji n+1. Ten permanentny stan niewiadomej jest źródłem frustracji i mnożenia się błędów i niedociągnięć. Prawię słyszę, jak krzyczycie do mnie o specyfikacji projektowej. Błogosławieni ci, którzy mają specyfikację i klienta, który się jej trzyma. Z mojego doświadczenia wynika, że specyfikacja często jest (jeżeli jest) ogólnym dokumentem, do którego nikt się nie modli. Skoro można pisać poprawki do konstytucji, to czemu nie można zmieniać specyfikacji? I zmienia się specyfikacje aż do momentu, gdy programiści osiągają stan apatii, w którym, często pod wpływem aresztu finansowego, zgadzają się na wszystko jak leci.

Przykład z mojego życia. Klient przychodzi i pragnie sklepu internetowego. Piszemy. Po wykonaniu trzech czwartych projektu następuje piwot, ponieważ klient klienta zmienił zapotrzebowanie. Na podstawie wykonanej pracy mamy zrobić platformę serwującą filmy na żądanie. Niby można, wystarczy ubić koszyk, zmienić profile użytkowników, przerobić trochę kategorie. Da się, są pieniądze. Mijają miesiące. W międzyczasie otrzymujemy przykaz, żeby używać FreeBSD jako platformy. Administrator klienta nie przepada za Linuksem.

Co dalej? Piwot. Klient klienta zbankrutował. Nie można wyrzucić tyle pracy. Przeróbmy to na chmurową platformę, która będzie spięta z Google Apps i będzie potrafiła odpalać oprogramowanie Windowsa przez serwer Citriksa. Aha, zmieńmy też platformę na Windows 2003 i IIS.

Po dwóch latach napisałem, że już dłużej nie mogę, że nie wiem już, co się dzieje w kodzie. Projekt, który zeżarł wiele tysięcy dolarów i wepchnął mnie w zawodową depresję, zostaje spuszczony w kiblu.

Łatwość modyfikacji oprogramowania powoduje, że programiści wszelkiej maści muszą posiadać zmyślone moce Nostradamusa albo być twardzielami, którzy potrafią utrzymać świętość specyfikacji. Koderzy dużo lepiej kodują niż negocjują, dlatego mamy całe masy niespełnionych Nostradamusów i oprogramowanie, które zaciągnęło taki dług technologiczny, że najłatwiej spłacić go butelką benzyny i zapałką.

Ile lat buduje się mosty, stawia domy? Kilka. Inne branże miały czas zakumulować know-how. Programiści chorują chronicznie na brak dobrych wzorców projektowych i ich nieznajomość połączoną z ostrym zapaleniem wyrostka Nie Wynaleziono Tutaj. Dodatkowym problemem jest ciągłe wywracanie technologii do góry nogami. Wczoraj zdecentralizowane dziś się centralizuje, by pojutrze rozproszyć. I choć teoria leżąca u podstaw pisania kodu jest w miarę jednolita, to zmieniają się miejsca, w których wychodzą problemy. Warstwy abstrakcji przykrywają poprzednie warstwy abstrakcji, powodując totalne rozwarstwienie pomiędzy wcześniejszą generacją programistów a generacją obecną. Dorzućmy do tego nieprawdopodobny (nie bez powodów) konserwatyzm wśród zawodowych klikaczy i mamy sytuację, w której dwóch programistów może posiadać sześć rozwiązań problemu. Każdy z nich nie mrugnie nawet okiem, usprawiedliwiając swój wybór. Dodajmy do mikstury świeżych autorów programów, którzy nie zakrzepli jeszcze w swoich schematach i każdy problem rozwiązują, dodając do stosu modne, nieprzetestowane technologie i uzyskujemy totalny kociokwik bibliotek, serwerów i metodologii przebijających swoim spektakularnym końcem dziewiczy rejs Titanica.

Przez pięćdziesiąt lat programowanie zmieniło się tak bardzo, że nie zmieniło się w ogóle. To znów urodziło eksperymentatorów z ciągotami do konserwatyzmu. Tymczasem stała grawitacyjna, wzory na objętość i materiałoznawstwo zdają się trwać. Oni mają ewolucję, a my krwawe rewolucje, które niosą na sztandarach hasło, że „Tym Razem Będzie Dobrze”.

Wiedza. Nie oszukujmy się, można być programistą, kompletnie ignorując jakiekolwiek dziedziny nauki. Kilkuset niezmiernie łebskich gości pisze narzędzia dla niedomytych mas. Niedomyte masy są tak dobre w rozwiązywaniu problemu, jak dobre narzędzia otrzymają od łebskiej elity. Wystarczy jednak wykonać jeden krok poza sferę kompetencji narzędzi, aby przekonać się, jak bardzo przeciętny programista jest w dupie. Bycie w ciemnej dupie nie jest fantastycznym doświadczeniem, dlatego też reakcją obronną jest naginanie dostępnych narzędzi do problemów. Człowiek krojący chleb piłą łańcuchową, człowiek, który ma bazę danych i wszystkie problemy potrafi przydusić tak, aby zamknęły się w SELECT/INSERT/DELETE/UPDATE. Jeden jest najedzony, a drugi ma rozwiązany problem, ale z szerszej perspektywy obaj wyglądają na durnych i lekko zagubionych.

Napisałem fantastyczną bibliotekę do obsługi aplikacji typu data-driven. Schemat bazy jest ekstremalnie generyczny, wszystko można zostawić użytkownikowi. Potem pojawiły się pierwsze problemy: jak rozpoznać, że grupa rekordów już istnieje i należy ją zaktualizować? Trzeba dodać unikalne indeksy. A co z polami o konkretnym typie, które topią się w bezpłciowym schemacie? Trzeba je ewaluować i trzymać cztery kopie tak, żeby dało się wykonać operacje via wbudowany ORM. Zanim się ocknąłem, reimplementowałem bazę danych w bazie danych, w kodzie we frameworku. Wyświetlenie głupiej tabelki zajmuje ORM-owi wieki i generuje kilka trylionów zapytań. Nie rozumiałem problemu, miałem młotek, dookoła mnie same gwoździe. Powbijałem je trzonkiem młotka i uznałem, że wszystko jest w jak najlepszym porządku.

Mimo to uważam, że nie jestem totalnym kretynem. Jestem produktem środowiska, mód i narzędzi. Ostatecznie doczytałem trochę teorii i ponaprawiałem (z pomocą [Patrysa](http://room-303.com/blog/[/ref] bardziej porąbane miejsca. Kod nie szedł jeszcze na produkcję, ale przecież mógł.

Łatwość, z jaką przychodzi nam budowanie rozwiązań dla oczywistych problemów, włącza nam tunelowe widzenie i wiąże ręce.

Czyli co, nie ma ani krzty nauki, metodologii i dobrych wzorców w całym programistycznym świecie? Skądże, jest coraz lepiej. Coraz lepsze narzędzia, coraz większy zasób wiedzy i metodologie projektowe pomagają nam wydźwignąć się z bagna niekompetencji. Nauczymy się rozwiązywać problemy, przed którymi stajemy zupełnie na golasa, będziemy bohaterami własnych historii.

Do czasu, aż przyjdzie kolejna rewolucja. Wtedy będziemy znów w dupie. I mogę poradzić tylko naukę gry na harmonijce i metalowy kubek, którym będziemy wybijać rytm o nasze superlekkie laptopy, śpiewając:

Nobody knows the trouble I’ve seen

Nobody knows my sorrow

Nobody knows the trouble I’ve seen

Glory hallelujah!

Sometimes I’m up, sometimes I’m down

Oh, yes, Lord

Sometimes I’m almost to the ground

Oh, yes, Lord