Jednoduchost jako výhoda prvních projektů
Vojtěch Bobek, Zakladatel
Když člověk začíná nový projekt, je velmi snadné si hned na začátku představit jeho finální podobu.
Nebude to jen jednoduchá aplikace. Bude mít několik typů uživatelů, vlastní administraci, notifikace, analytiku, několik integrací, mobilní verzi a možná rovnou AI asistenta. Databáze bude připravená na budoucí růst, architektura modulární a celý systém navržený tak, aby se dal jednou rozšířit na mnohem větší produkt.
Na papíře to působí jako dobré plánování. Často si tím ale vytvoříme několik měsíců práce ještě předtím, než jsme dokončili první skutečně užitečnou věc.
Čím více projektů jsem stavěl, tím víc mám pocit, že jednou z nejdůležitějších schopností na jejich začátku není přijít s dostatečně velkou vizí, ale naopak dokázat z ní dočasně většinu odstranit.
Ne proto, že bychom měli stavět malé produkty navždy. Jednodušší první verze nám ale umožní rychleji pochopit samotný problém, dokončit základní proces od začátku do konce a zjistit, která komplexita je skutečně potřeba.
V rané fázi totiž podle mě není největším rizikem to, že produkt umí málo. Mnohem častěji je problémem, že jsme si vytvořili tolik věcí k řešení najednou, že už nedokážeme rozlišit, co je skutečně důležité.
Komplexita roste rychleji, než se na začátku zdá
Přidání jedné funkce málokdy znamená jen jednu další funkci.
Řekněme, že vytváříme jednoduchou aplikaci pro rezervace. Na začátku potřebujeme zákazníka, termín a možnost rezervaci vytvořit nebo zrušit.
Potom přidáme více provozoven. To znamená přiřazovat termíny ke konkrétním místům. Přidáme zaměstnance, takže musíme řešit jejich dostupnost. Následně chceme uživatelské účty, různá oprávnění, e-mailová upozornění, platby předem a možnost změnit termín.
Každá z těchto věcí je sama o sobě rozumná. Jenže se postupně začnou ovlivňovat.
Co když zaměstnanec pracuje ve více provozovnách? Kdo může změnit zaplacenou rezervaci? Co se stane s platbou po zrušení termínu? Kdo dostane upozornění, pokud rezervaci upraví administrátor? Jak se zachová systém, když klient přesune rezervaci k jinému zaměstnanci?
Počet funkcí roste postupně, ale počet vztahů mezi nimi může růst mnohem rychleji.
Proto bývají první odhady tak zrádné. Každý požadavek vypadá jako několik hodin nebo dnů práce, jenže většina skutečné složitosti vznikne až na jejich hranicích.
V raném projektu pak velmi snadno strávíme většinu času řešením interakcí mezi funkcemi, které jsme zatím ani nepotřebovali.
Jednoduchost není totéž jako primitivnost
Když řeknu, že bych první verzi držel jednoduchou, nemyslím tím postavit něco ledabyle.
Jednoduchý systém může mít čistý kód, rozumně navržená data, ošetřené chyby a základní testy. Jen záměrně řeší menší množství problémů.
To je důležitý rozdíl.
Můžeme například vytvořit rezervace pouze pro jednu provozovnu, ale udělat celý proces dobře: zákazník si vybere termín, rezervaci potvrdí, dostane správnou informaci a administrátor ji dokáže spravovat.
Teprve když tahle základní cesta funguje, přidáme další vrstvu.
Opačný postup by byl vytvořit najednou podporu pěti provozoven, složitý systém oprávnění a několik druhů rezervací, zatímco samotné vytvoření rezervace ještě není dotažené.
První varianta umí méně, ale už existuje něco, co lze skutečně použít. Druhá má větší ambici, ale velká část její hodnoty je pořád jen v rozpracovaném kódu.
Proto bych jednoduchost nevnímal jako nižší technickou úroveň. Spíš jako disciplínu v rozhodování o rozsahu.
Každá další vrstva zabírá část pozornosti
Komplexita nestojí jen čas na implementaci. Zabírá také mentální kapacitu.
Když pracuji na malém systému, dokážu jeho velkou část držet v hlavě. Vím, jak data procházejí aplikací, kde se mění a co která část ovlivňuje.
S každým dalším konceptem se tato mapa zvětšuje.
Najednou musím přemýšlet nad více typy uživatelů, stavy, pravidly, integracemi a výjimkami. Při každé změně se vracím k otázce, jestli jsem nezapomněl na nějakou kombinaci, kterou jsem přidal před několika týdny.
Část pozornosti tak přestávám věnovat samotnému problému a začínám ji spotřebovávat na správu komplexity, kterou jsem si vytvořil.
To se samozřejmě u větších systémů nedá úplně odstranit. Proto existují moduly, abstrakce, typové systémy, testy a další nástroje, které nám pomáhají složitost zvládat.
V začátku projektu je ale často ještě lepší možnost: část komplexity vůbec nevytvořit.
Pokud zatím nepotřebujeme tři uživatelské role, nemusíme navrhovat univerzální systém oprávnění. Pokud máme jediný způsob platby, není nutné od prvního dne stavět obecnou platební vrstvu pro pět poskytovatelů.
Kvalitní abstrakce dokáže komplexitu organizovat. Nejjednodušší abstrakce je ale pořád ta, kterou zatím nepotřebujeme.
Dokončený malý projekt vás naučí víc než obrovský projekt hotový z třiceti procent
Tohle je podle mě obzvlášť důležité u prvních vlastních projektů.
Je lákavé začít něčím velkým. Vlastní sociální sítí, rozsáhlým SaaS, tržištěm nebo komplexní mobilní aplikací. Člověk má díky tomu pocit, že pracuje na něčem skutečně zajímavém.
Problém je, že pokud se nikdy nedostane za prvních třicet procent, velká část vývoje mu zůstane skrytá.
Nikdy nemusí řešit skutečné nasazení. Migraci dat. Zpětnou vazbu uživatelů. Problémy, které vzniknou až po několika týdnech používání. Údržbu funkce, kterou napsal před půl rokem. Ani okamžik, kdy se musí rozhodnout, že produkt je dostatečně hotový na to, aby ho ukázal ostatním.
Malý dokončený projekt člověka protáhne celým cyklem.
Nápadem, návrhem, implementací, testováním, nasazením, používáním i opravami.
A právě celý tento cyklus podle mě vytváří mnohem větší zkušenost než opakované začínání velkých projektů.
To samozřejmě neznamená, že bychom se měli celý život držet malých aplikací. Jen mi přijde užitečnější postupně zvětšovat složitost problémů, které dokážeme dokončit, než rovnou skočit do systému, jehož komplexitu ještě neumíme řídit.
Scope se téměř vždycky zvětší i bez naší pomoci
Další důvod, proč začínat menší, je prostý: během práce stejně objevíme nové věci.
Původně potřebujeme jednoduchý formulář. Během implementace zjistíme, že musíme řešit jeho stav po chybě.
Přidáme import dat a následně zjistíme, že potřebujeme zobrazit průběh, řešit duplicity a umožnit uživateli chybný import zopakovat.
Spustíme první verzi a zákazníci začnou používat produkt způsobem, se kterým jsme nepočítali.
Rozsah projektu tedy přirozeně roste i bez toho, abychom ho uměle nafukovali na začátku.
Pokud začneme s plánem, který už od prvního dne využívá veškerou dostupnou kapacitu, každé nové zjištění znamená zpoždění nebo kompromis.
Naopak menší počáteční rozsah vytváří prostor pro věci, které zatím neznáme.
A těch bude vždycky dost.
Budoucnost projektu známe méně, než si myslíme
Velká část zbytečné komplexity vzniká ze snahy připravit se na budoucnost.
„Jednou budeme podporovat více zemí.“
„Později z toho uděláme platformu.“
„Až budeme mít enterprise zákazníky, budou potřebovat vlastní role.“
Všechny tyto věci mohou být pravda.
Jen zatím nejsou.
Problém nastává, když kvůli hypotetické budoucnosti začneme měnit dnešní architekturu způsobem, který současný problém vůbec nepotřebuje.
To neznamená psát kód bez jakéhokoliv výhledu. Pokud už dnes víme, že za měsíc spouštíme druhou měnu, bylo by absurdní natvrdo předpokládat koruny úplně všude.
Rozdíl je mezi pravděpodobným známým požadavkem a neurčitou představou typu „jednou to možná budeme potřebovat“.
Čím vzdálenější budoucnost se snažíme předvídat, tím větší je pravděpodobnost, že budujeme flexibilitu pro scénář, který nikdy nenastane — zatímco skutečné požadavky přijdou z úplně jiné strany.
Proto bych raději stavěl jednoduchý systém, který lze rozumně změnit, než složitý systém připravený na přesnou budoucnost, kterou jsme si sami vymysleli.
Omezení často vedou k lepšímu produktu
Když si řekneme, že první verze musí být hotová za dva týdny, nemůžeme udělat všechno.
Musíme se rozhodovat.
Která část je opravdu zásadní? Bez čeho produkt nedává smysl? Co můžeme vyřešit ručně? Co může uživatel zatím udělat jiným způsobem? Které pohodlí není pro první verzi nutné?
Takové omezení může působit nepříjemně, ale zároveň nás nutí pochopit jádro produktu.
Pokud nedokážeme říct, co musí zůstat ve chvíli, kdy máme polovinu času, možná sami nevíme, kde jeho hlavní hodnota leží.
Právě proto mi přijdou omezení často produktivní.
Nutí nás odlišit základní problém od věcí, které jsou pouze příjemné navíc.
A velmi často zjistíme, že produkt potřebuje méně, než jsme si původně představovali.
Jednoduché řešení navíc poskytuje čistší zpětnou vazbu
Řekněme, že současně změníme onboarding, cenový model, hlavní obrazovku, navigaci a způsob používání klíčové funkce.
Výsledky se zlepší.
Co přesně pomohlo?
Nevíme.
Nebo se naopak zhorší a jsme ve stejné situaci.
Čím větší množství změn spojíme dohromady, tím obtížnější je z jejich výsledku něco vyčíst.
Jednoduchost proto pomáhá i při učení.
Když první verze testuje jednu jasnou hypotézu a obsahuje minimum dalších proměnných, zpětná vazba je mnohem čitelnější. Snáz poznáme, jestli samotná myšlenka funguje, nebo ne.
To je podle mě důležité hlavně v rané fázi, kdy má produkt mnohem více otázek než odpovědí.
V takové chvíli není potřeba ukázat, jak velký systém jsme schopni postavit. Potřebujeme se co nejrychleji dozvědět, které části systému vůbec stojí za to jednou postavit ve velkém.
Jednoduchost může být dočasná
Častou obavou je, že když první verzi příliš zjednodušíme, později budeme všechno předělávat.
Někdy ano.
A nemusí to být chyba.
Pokud nám jednoduché řešení během několika týdnů umožní zjistit, že konkrétní směr funguje, může dávat smysl část systému později přepracovat se znalostmi, které jsme na začátku neměli.
To může být levnější než půl roku navrhovat obecnou architekturu na základě předpokladů.
Samozřejmě existují rozhodnutí, u kterých je předělávání velmi drahé — například práce s kritickými daty, bezpečnost nebo veřejné API, na kterém začnou záviset jiné systémy. Tam se vyplatí přemýšlet více dopředu.
U velké části prvních produktových rozhodnutí ale platí opak. Jsou vratná a právě schopnost je později změnit nám umožňuje dnes být jednodušší.
Nemusíme mít správnou architekturu pro deset milionů uživatelů, pokud zatím nemáme prvních deset.
Potřebujeme hlavně řešení, které dnešní problém vyřeší dobře a nebude nám zbytečně bránit ve chvíli, kdy se o skutečné budoucnosti dozvíme něco víc.
Jak bych rozsah prvního projektu zmenšoval
Když mám pocit, že projekt začíná být příliš velký, snažím se nejdřív odstranit věci, které nepatří do jeho hlavní cesty.
Pokud je cílem rezervačního systému umožnit zákazníkovi rezervovat termín, zajímá mě nejdřív celý proces od výběru po potvrzení. Vlastní analytický dashboard může přijít později. Stejně tak pokročilá správa oprávnění nebo automatizace, pokud zatím proces obsluhuje jeden člověk.
Další kandidáti jsou obecná řešení pro problémy, které dnes mají jedinou variantu. Pokud podporujeme jeden typ objektu, nemusíme nutně hned vytvářet obecný systém pro deset budoucích typů.
Podíval bych se také na věci, které lze první týdny řešit ručně. Není cílem vytvořit ruční provoz navždy, ale pokud manuální krok stojí deset minut týdně a jeho automatizace tři dny vývoje, může být velmi rozumné těch deset minut zatím přijmout.
A nakonec bych hledal věci, které jsou hlavně příjemné. Lepší animace, deset možností nastavení, třetí způsob filtrování nebo pokročilá personalizace mohou produkt později výrazně zlepšit, ale pokud bez nich dokážeme ověřit hlavní hodnotu, nemusí patřit do první verze.
Výsledkem nemá být ořezaný produkt, který nedokáže nic užitečného.
Má to být nejmenší verze, která dokáže jeden důležitý proces opravdu dobře dokončit.
Jak poznat, že už jsme jednoduchost přehnali?
Stejně jako lze produkt zbytečně překombinovat, lze ho i zjednodušit natolik, že přestane řešit samotný problém.
Pokud odstraníme funkci, bez které zákazník nedokáže dokončit hlavní úkol, neušetřili jsme rozsah. Odstranili jsme hodnotu.
Stejně tak příliš ruční proces může vytvořit výsledek, který není realistické později poskytovat za plánovanou cenu. A prototyp může být tak vzdálený skutečnému používání, že feedback z něj nebude příliš užitečný.
Proto se nesnažím minimalizovat počet funkcí za každou cenu.
Snažím se minimalizovat počet věcí, které nejsou potřeba k ověření nebo doručení hlavní hodnoty.
To je podstatně praktičtější hranice.
Jednoduchost není cíl sama o sobě. Je to nástroj, který nám pomáhá soustředit omezenou kapacitu na to, co je v danou chvíli skutečně důležité.
Proč tedy jednoduchost v prvních projektech tak často vyhrává?
Protože první projekt většinou netrpí nedostatkem potenciálních funkcí.
Trpí nedostatkem času, informací a zkušenosti.
Každá zbytečná vrstva přidává další rozhodnutí, další možné chyby a další místo, kde můžeme uvíznout ještě předtím, než se dostaneme k hlavní hodnotě produktu.
Jednodušší první verze nám naopak umožní celý systém lépe pochopit, dokončit jej, dostat ho před skutečné uživatele a získat informace, podle kterých můžeme další komplexitu přidávat vědomě.
Proto dnes při začátku nového projektu nepřemýšlím jen nad tím, co všechno by jednou mohl umět.
Mnohem důležitější mi připadá otázka:
„Co všechno můžeme zatím odstranit, aniž bychom přišli o důvod, proč tento produkt vůbec vzniká?“
Pokud na ni dokážeme dobře odpovědět, často zjistíme, že první verze může být výrazně menší, než jsme si představovali.
A právě díky tomu má mnohem větší šanci skutečně vzniknout.
Zdroje
- Frederick P. Brooks Jr. — The Mythical Man-Month
- John Gall — Systemantics
- John Sweller — práce o teorii kognitivní zátěže

