Thursday, August 2, 2012

Zawsze pracuj na twardych danych

Czasem zdarza Ci się spotkać z jakimś problemem związanym z algorytmem, architekturą, sprawami organizacyjnymi itp. Sporo pracuję z ludźmi nad rozwiązywaniem problemów tego rodzaju i zauważyłem, że czasem umysł albo nasze własne przyzwyczajenia utrudniają nam znalezienie rozwiązania. Poniżej spisałem kilka rzeczy, o których warto pamiętać, gdy szukasz rozwiązania jakiejś kwestii. Być może te rzeczy wydadzą Ci się oczywiste, ale zdążyłem się już przekonać, że oczywistych rzeczy nauczyć się najtrudniej. Oczywiste jest na przykład, że korzystniej dla zdrowia swojego i innych być zrelaksowanym, a mimo to obroty z leków uspokajających są obrzydliwie wielkie. Rzecz trudną i oczywistą poznasz po tym, że wszyscy o niej mówią i wszyscy wiedzą, ale mało kto ją robi.

Myśleć o problemie, czy o rozwiązaniu?

Lubimy czasem powtarzać zasłyszane frazesy. Jednym z nich jest "myśl o rozwiązaniu zamiast o problemie". To mądre zdanie w powszechnym użytku staje się frazesem. Na czym polega frazesowanie, tej światłej myśli? Otóż przede wszystkich chodzi to o "koncentrowanie się" na problemie. O sytuacje, w których tak obsesyjnie myślisz o danym błędzie lub sprawie do rozwiązania, że to myślenie przesłania kreatywności i nie pozwala dostrzec rozwiązań. To trochę tak, jakbyś spędził kilka dni na projektowaniu warstwy dostępu do danych z użyciem Hibernate, stosując najbardziej wyrafinowane mapowania i ani razu nie zastanowił się nad pytaniem Czy Hibernate jest tu w ogóle potrzebny?


Przede wszystkim pamiętajmy, że nie znajdziesz rozwiązania, jeśli nie rozumiesz natury problemu, z którym masz do czynienia. Najpierwszejsze pytania, które trzeba sobie zadać, to O co właściwie chodzi? Z czym właściwie mam do czynienia? Jak to działa? Co po kolei się wydarza, że jest taki a taki rezultat?

Posługuj językiem twardych liczb

I tu najczęściej jest klops. Pewien programista, z którym ostatnio pracowałem mierzył się ze złośliwym problem. Miał stworzyć transformaty migrujące dane z jednego systemu do drugiego. Z różnych powodów posiadał w tamtej chwili szczątkową wiedzę na dany temat, co więcej polecono oszacować mu czas realizacji zadania. Do tego momentu jeszcze wszystko w miarę gra.

Sformułowanie problemu jest kluczowe
Kłopot tkwił w tym, w jaki konkretnie sposób ten programista podchodził do pracy. Otóż, gdy tłumaczył mi na czym polega rzecz mówił mniej więcej tak "powiedzmy, że mamy obiekt A i A'. A' znaczy w tym systemie co innego niż w tamtym A. I teraz nie do końca wiemy jak stworzyć taką trasnformatę, jak zmapować obiekty na siebie. Jakie są podejścia do tego typu zadań?" Odpowiadam: nie ma żadnych podejść. I nie wynika to z natury problemu, lecz z błędnego jego sformułowania.

Zauważ, że programista sformułował problem na dość wysokim poziomie abstrakcji. Uogólnił go, jeszcze nie w pełni rozumiejąc w czym rzecz. W ten sposób przeszedł do bardzo abstrakcyjnego myślenia. I tak powiem...konkretne sformułowanie problemu => konkretne rozwiązanie, abstrakcyjne sformułowanie problemu => abstrakcyjne rozwiązanie. Dlaczego? Dlatego, że przy tego typu sformułowaniach, za każdym razem, gdy wpadnie Ci do głowy jakieś rozwiązanie, jesteś tak zteoretyzować problem, że znajdziesz takie konteksty i takie przypadki szczególne, że rozwiązanie będzie do bani.

Na ogólnym poziomie nie ma rozwiązań, problemów, owszem, jest od groma. Rozwiązania istnieją tylko w konkretnych rzeczywistych mierzalnych danych. A zatem zawsze pracuj na twardych liczbach, gdy tylko próbujesz rozwiązać jakiś problem. Dopiero potem, gdy będziesz już mieć wystarczająco wyraźny obraz rzeczywistości, będziesz mógł postawić hipotezy rozwiązania, a następnie próbować je w ogólnym przypadku. W tej właśnie kolejności: najpierw konkret, potem abstrahowanie. Nigdy odwrotnie.

Procedura postępowania

Jak zatem wygląda procedura działania? Posługując się w/w przykładem z transformatami, mamy:
  1. Zrozum wszystkie przypadki szczególne (Co reprezentują poszczególne obiekty w każdym systemów? Jakie jest ich znaczenie biznesowe? Jakie informacje przechowują? Jakie są reguły spójności danych?)
  2. Zbuduj rozwiązanie dla najprostszego przypadku (Napisz transformatę dla konwersji pojedynczych pól)
  3. Zbuduj rozwiązanie dla każdego przypadku szczególnego (Stwórz transformatę dla: konwersji prostego obiektu, dwóch obiektów w relacji 1-1, dwóch obiektów w relacji *-1...)
  4. Poszukaj części wspólnej (Czy, któraś z kolejnych transformat, "załatwia" poprzednie? Czy można napisać jedną transformatę dla 90% przypadków, a pozostałe 10% przypadków obsłużyć małymi transformatami?)
  5. itd

Tak, to zajmuje czas. Czasem dużo czasu. Ale z każdą godziną, rozwiązanie pokrywa coraz większą część problemu. Przeciwnie, gdy od samego początku próbujesz rozwiązać teoretyczny ogólny problem, to z każdą godziną problem się komplikuje, a rozwiązań nie ma.