Už dlouho jsem tu nevystavil takový ten klasický plkací článek, kde jen o něčem filozofuji. Kdysi jsem měl takové články v oblibě, tak jsem se rozhodl, že to s nimi zase zkusím.
Bude to reakce nebo spíš doplnění Dagiho článku Technologický dluh vs. Overengineering. Chci se k tomu vyjádřit, protože jsem asi jedním z důvodů, proč nad tímto tématem Dagi tak hloubá.
Samozřejmě nehloubá nad tím, jestli máme psát špagety kód nebo ne. Tam není co řešit. Špagety do produkčního kódu prostě nepatří. Tečka. Ale máme hromadu případu, kdy situace není tak černobílá.
Ať se nám to lépe představuje, předveďme si to na příkladu dvou naprosto imaginárních programátorů, kteří mají k programování trochu odlišný přístup. Programátor R. nad věcmi víc uvažuje, snaží se je dělat co nejlépe a nejčistěji. Programátor L. je více pragmatický a hlavní je pro něj jednoduchost a co nejméně práce. Je možná tak trochu líný.
Takže L. předvádí svůj úžasně napsaný minimalistický kód a R. mu říká: “Hmm, tady ten krásný kousek kódu by bylo pěkné vytáhnout do znovupoužitelného modulu, ať si i ostatní programátoři mohou užít výplodu tvé geniality“. A na to mu L., hrozící se další dřiny, odpovídá: „Chápu tvůj neskonalý obdiv k mému veledílu, ale bojím se, že tento modul stejně nikdo nebude potřebovat. Byla by to jen zbytečná práce navíc.“
Tak a teď bych vás chtěl poprosit, ať se zamyslíte kdo z nich má pravdu. Je lepší strávit nějaký čas vytahováním kódu do separátního modulu a tím zvyšovat komplexitu nebo je lepší držet kód méně čistý, ale jednodušší? Je lepší jednoduchý nebo znovupoužitelný kód? Nějaké nápady? Řešení?
Odpověď je samozřejmě klasická. Zní: „Přijde na to.“ Překvapivě totiž záleží hlavně na tom, jestli se ten modul opravdu použije ještě někde jinde nebo ne. Pokud ano, pak se ta práce vyplatila a vyhnuli jsme se duplikování kódu. Takže ten modul snížil technologický dluh.
Pokud ale ten modul bude opravdu použit jenom z toho jednoho místa, tak jsme to evidentně překombinovali a máme zbytečně složitý kód.
Fór je v tom, že dopředu často nevíme, o který případ se jedná. Jak zní můj oblíbený citát: “Je obtížné cokoliv předvídat, obzvláště pak budoucnost“. A to je zdroj té neshody. Jedna strana tvrdí, že ten modul můžeme vytvořit, až to bude potřeba. Druhá strana zase tuší, že když se to neudělá teď, tak už se k tomu nedostaneme nikdy. Jednou mají pravdu jedni, jindy zase ti druzí.
Neplatí to samozřejmě jen o modulech, ale i o většině ostatních programátorských fíglech. Takže vrstvení aplikace je dobré, ale jen pokud je opravdu potřeba. Webové služby jsou dobré, ale jen pokud jsou opravdu potřeba. ORM je dobré, ale jen pokud je opravdu potřeba … Je mi skoro trapné skončit takovou samozřejmostí, ale co se dá dělat.
Myslím si že obě strategie mají svůj smysl. Jakmile ale jedna převažuje nad druhou je něco špatně. Kolega to s overengineeringem přehání přesně tak jak popisujete s novými moduly a vznikají potom zbytečné projekty a tím zpomaluje ostatní. Navíc pokud ty moduly jsou stejně použité v jednom projektu a pokud se releasujou nové verze tak se musí releasnout všechno najednou takže oddělení ztrácí na významu.
Takže result:
Je lepší jednoduchý nebo znovupoužitelný kód? – Oba, pokud se to nepřehání:-)
Nápad řešení? – Myslím si že cílem má být co nejvyšší efektivita, nejen okamžitá ale i v budoucnu, takže pružně reagovat pokud zjistíme že se nějaký kód duplikuje a zobecnit ho případně oddělit. Taktéž pokud vidíme zbytečnou obecnost tak tu část zjednodušit. “Pokud na to není čas” tak si z toho alespoň pro příště vzít ponaučení 🙂
Taky se snažím balancovat na pragmatické hranici a pochopitelně se ne vždy trefím. Jednou jsem honil deadline (částečně po předchozím programátorovi) a říkal jsem si, že je nepravděpodobné, že by jednu položku mělo v budoucnu spravovat více lidí. Tak jsem časem holt refaktoroval. Jinde mi zase bylo řečeno, ať si to nekomplikuju…
Ale dodal bych ještě jednu poznámku: Někdy je kód v jedné třídě prostě velký a hodí se pro přehlednost ‘rozbít’, i pokud se nevyužije jinde. Ostatně, část privátních metod tomu odpovídá. A vzpomínám si na jiný filozofický článek (možná od Dagiho, možná dokonce odsud), který poznamenával, že lepší než dokumentace v komentářích je rozbití do popisných podmetod.
Pripada mi ze michate v clanku a komentarich par veci dohromady, tak to zkusim rozdelit a pridat nazor:
1. tridy a metody maji byt rozumne male a delat “jednu” vec. To je proste zakladni predpoklad cisteho kodu.
2. delat nejaky obecny modul dopredu ma smysl jen v pripade, ze vime ze v pristich tydnech ci mesicich to nekdo opravdu pouzije. Pokud ne, tak jednak to muze byt zbytecna prace, druhak neodhadneme interface dostatecne dobre a stejne se to bude muset upravit.
3. argument “pak nebude cas” je scestny. U kazdeho vyvoje nad existujicim kodem je nutno delat predelavky, pokud na ne neni cas, tak to stejne dobre nedopadne at uz jsme tomu predtim sli naproti nebo ne.
Uz pred davnym casem jsem cetl nejaky clanek o tom, jak jsou cesi posedli delat veci hned napoprve dobre, jak treba amikum nevadi pristup zkusit a zahodit. Nevim co je na tom pravdy, ale obcas si na to vzpomenu a hned se mi lepe programuje. Staci se smirit s tim, ze predelavky jsou beznou soucasti zivota programatora/analytika, nebat se jich, nebat se napsat kod lepe a stary zahodit. Pokud je dostatecne testovany a je cas na pripravu, tak to neni problem.
Nejlejší programátoři na světě jsou ti, co mají schopnost empatie se zákazníkem. Většinou se podobnými věcmi nezabývají, připadají jim naprosto přirozené. Rozhoduje vždy a jen to, jestli se to ve výsledku vyplatí. Můžeme tomu dávat různé nálepky, nic to na tom nezmění.
Takových programátorů/designérů/projekt manažerů je zatraceně málo 🙂
Pokud bych měl odpovědět na tu základní otázku v textu, tak po letech zkušeností říkám NE jakýmkoliv úpravám, o kterých jasně nevíme, že je nyní nebo v budoucnu budeme potřebovat. Zkušenosti mě v tomto jen utvrzují, navíc je to jedno ze základních pravidel agilních přístupů (konkrétně XP).
Další velká zkušenost je ta, že napoprvé není nic dokonalé a pro návrh API to platí dvojnásobně.