Union Types vs. Intersection Types

Tento týden vyjde nová verze PHPStanu, která bude chápat váš kód opět o mnoho lépe. Zavádí mimo jiné tzv. intersection types. Jelikož jde o téma, které stojí na vlastních nohou (není ho vždy potřeba vázat se statickou analýzou) a všichni, kdo v dnešní době píšou moderní webové aplikace, by se o type theory měli zajímat, sepsal jsem porovnání union typů a intersection typů.

Asynchronní PHP

V polovině dubna jsem si vyzkoušel nový formát předávání zkušeností – přednášku přímo z obýváku. Naživo si mě naladilo asi 80 lidí, kteří měli možnost i klást otázka přes chat, na které jsem mezi připravenými bloky odpovídal. Byla to super zkušenost, kterou si rád zopakuji.

Asynchronní kód už dávno není doménou jen Node.js. Abyste si vyzkoušeli psát a provozovat aplikaci, která dokáže dělat více věcí naráz, nemusíte se učit programovat v jiné technologii, vystačíte si s PHP, které vás příjemně překvapí svým výkonem a možnostmi.
Vysvětlíme si, co přesně asynchronnost znamená, kde všude se s ní dá setkat a kdy se vyplatí ji použít. Ukážeme si, jak přesně fungují promises a napíšeme si kód, který je využívá a poskytuje.
V druhé polovině livestreamu pak předvedu konkrétní knihovny a postupy pro nejčastější I/O potřeby, tedy asynchronní HTTP požadavky, SQL dotazy a přístupy na filesystém.

Na livestream i záznam jsem měl skvělé ohlasy. Z jednoho projektu se mi ozvali s tím, že na základě mé přednášky vyměnili svůj dosavadní způsob paralelizace odchozích HTTP požadavků skrze forkování procesů právě za asynchronní princip s event loop a ušetřili tím spoustu paměti a výpočetního výkonu.

Usnadněte si práci silně typovaným kódem a statickou analýzou!

1. dubna jsem na konferenci Devel.cz mluvil o tom, jak si ušetřit práci při psaní testů, ale přesto mít spolehlivou aplikaci. Roli v tom hraje samozřejmě PHPStan, ale dodržování zmíněných tipů vede ke zvýšení čitelnosti a spolehlivosti kódu i bez použití statické analýzy.

Málokterý vývojář může s čistým svědomím tvrdit, že má 100 % kódu pokryto testy. Ale to nevadí. Ve většině reálných aplikací je nereálné a neekonomické toho dosáhnout. Ukážu, jak psát kód tak, aby vám na něj testy ani nechyběly, a přesto se na něj mohli spolehnout díky statické analýze. Představím nástroj PHPStan, který chyby v aplikaci hledá za vás. Po mé přednášce testy psát nepřestanete, ale zaměříte se s nimi na místa, kde se vyplatí.

Přednášku si můžete pustit se synchronizovanými slajdy zde, nebo mrkněte na oanotované slajdy níže.

Asynchronní zpracování s RabbitMQ

Loni v září jsem nasedl do auta a vydal se 600 kilometrů z Prahy na severovýchod k Varšavě. V odlehlém komplexu obřího hotelu Ossa se konala neméně obří konference PHPCon Poland 2016 s nabitým programem plným přednášek od místních i zahraničních speakerů. A já byl jedním z nich.

Připravil jsem si přednášku o RabbitMQ. Toto téma je mi velmi blízké, protože v PHP rád vyvádím netradiční věci odpoutané od klasického modelu „spusť se, vyřiď request a umři“. Použitím RabbitMQ či jiné message queue můžete zefektivnit svou aplikaci a třeba zařídit, aby vaši uživatelé obdrželi vyžádaný e-mail okamžitě a nikoli až při příštím spuštění skriptu pomocí Cronu.

Pokud si nechcete pouštět video, mrkněte na slidy. Jinak klikněte na ▶ níže:

Tři pilíře statické analýzy v PHP

Poslední dobou jsem posedlý statickou analýzou. Možnost objevovat chyby v kódu bez vynaložení úsilí je lákavá a skutečně funguje. Na blogu PHPStanu, jaké jsou dnes možnosti ohledně statické analýzy v PHP a jaké nástroje může každý začít hned využívat. Zmínil jsem samozřejmě i PHPStan.

PHPStan: hledání chyb v kódu bez psaní testů

Na blogu PHPStanu jsem se rozepsal o tom, na čem pracuji již několik let, z toho poslední rok intenzivně – na nástroji pro statickou analýzu PHP kódu. PHPStan hledá chyby, aniž by bylo třeba daný kód spouštět, čímž se blíží kompilátorům staticky typovaných jazyků. Využívá informací, které jsou k dispozici při parsování PHP kódu - typehinty, dokumentační komentáře a reflexi.

Různé vývojové verze PHPStanu nám už přes rok hlídají produkční kód ve Slevomatu a už mnohokrát včas na CI serveru odhalil chybu, která by se jinak dostala do produkce. Pochvalují si ho také vývojáři v Hele.cz, DámeJídlo.cz a Bonami.

Oproti podobným nástrojům nabízí především rychlost, rozšiřitelnost1 a různé nastavení striktnosti, aby vás napoprvé nezahltil nadbytečným množstvím chyb, ale pouze těmi nejzásadnějšími, a mohli jste ho tak rovnou začít používat.

Delší a podrobnější povídání o něm najdete na najdete na blogu PHPStanu nebo se rovnou podívejte do dokumentace, jak ho zprovoznit na svém projektu. V případě, že byste s integrací a nastavením chtěli pomoct, určitě se ozvěte.

  1. Pro popis magického chování tříd, které si dynamicky definují properties a metody pomocí implementace magických metod __get, __set a __call

Zkracování feedback loop

V odvětví softwarového vývoje existuje spousta best practices, které vedou ke zrychlení a zjednodušení práce programátora. O čistém a čitelném kódu, SOLID principech a testování bylo již napsáno mnoho a myslím si, že kdo chce, už to všechno dlouho dělá. Poslední dobou se ale zabývám něčím, co je pro fungování týmu vývojářů a jejich projektů neméně důležité a zásadní, ale v praxi to ještě příliš často nepotkávám, zato vidím důsledky absence tohoto postupu.

Řada článků a přednášek odrazuje od kompletního přepisu funkčního software a mají k tomu pádné důvody. Nutnost dohánět roky vývoje současné verze, nulová hodnota pro uživatele a nejistota, že to všechno vynaložené úsilí dopadne lépe. Kompletní přepis nikdy nedává smysl. V kontextu tohoto článku ho ale považuji pouze za jeden extrém na dlouhé škále různých řešení a chci ukázat, že lekce, které z něj plynou, lze aplikovat při každodenní práci, i když zrovna něco nepřepisujete od nuly a zdánlivě děláte vše dobře.

Jaký důvod mají týmy ke kompletnímu přepisu? Potřebují něco udělat jinak, než to v aktuálním projektu je, často si to chtějí jen vyzkoušet. Nikdo, ani sebevětší expert, často neví, jestli směr, kterým se vývoj ubírá, je správný. Proto bychom se to měli snažit zjistit co nejdříve, co nejrychleji získat zpětnou vazbu. Kámen úrazu tkví především v tom, že přepis trvá příliš dlouho a celé měsíce či roky týmy budují něco, u čeho nikdo netuší, jestli je to správně a jestli se to vyplatí. Tento problém se však netýká jen kompletních přepisů, ale i běžného iterativního vývoje.

Feedback loop, v češtině „kolečko zpětné vazby“, je základním kamenem jakékoli tvůrčí práce. Vždy byste se měli soustředit na to, abyste co nejdříve dostali zpětnou vazbu k vašemu výtvoru. Od kolegů, od hardwaru, od uživatelů i zákazníků. Jen tak si zajistíte, že stavíte něco, co má cenu.

Že se to někomu nedaří se dá navenek velmi snadno poznat. Z nedávné doby mě napadá např. ČEZ a jeho nový zákaznický systém:

Energetická společnost ČEZ přechází na nový zákaznický systém. Kvůli změně však není možné až do poloviny října provést jakoukoliv změnu v zákaznických smlouvách. Část zákazníků dostane se zpožděním roční vyúčtování.

Měsíc (!) nemůže jedna z největších českých společností hýbat s daty zákazníků. A to kvůli tomu, že nesbírali feedback k novému produktu průběžně, ale nasadili ho celý najednou a přišli příliš pozdě na to, že nefunguje.

Rychlejšího sběru zpětné vazby se dá dosáhnout častějšími releasy. To ale není jediná metrika, o kterou by se tým měl snažit. Zásadní je držet množství nového kódu, který není v produkci, na naprostém minimu. Kód, který není nasazený, představuje riziko.

Čím častěji budete nasazovat, tím menší změny v jedné dávce dostanete do produkce. S malými změnami se pojí řada výhod. Snadněji provedete poctivé a detailní code review. Máte větší šanci, že v kódu odhalíte problémy, pokud reviewujete desítky a nikoli tisíce řádků.

10 lines of code = 10 issues.
500 lines of code = „looks fine.“
twitter.com/iamdevloper

Čím menší změna, tím menší riziko, že se něco pokazí. Menší změny se snadno revertují. Krátké větve v Gitu se také daleko snadněji spravují, rebasují a mergují.

Koncentrace na rychlé získávání feedbacku vyžaduje změnu mindsetu. U každé změny, kterou provádíte, musíte uvažovat, jak ji provést tak, aby se dala ihned bez problému nasadit.

Při vývoji nové funkcionality vás typicky čeká spousta „přípravných“ prací, na kterých pak novou funkcionalitu stavíte. Takové refaktoringy by neměly nic rozbít a měly by jít rovnou nasadit. Tím si ověříte, že fungují a opravíte případné chyby, kterých určitě nebude tolik, jako kdybyste je nasazovali až ve velkém finálním balíku změn s hotovou celou funkcionalitou. Určitě je výhodnější opravovat 15× dvě chyby v průběhu několika týdnů, než třicet chyb najednou.

Kromě toho, že sbíráte feedback na své změny v produkci, vám poděkují i kolegové, se kterými sdílíte váš čerstvý kód a mohou z něj rovnou těžit ve svém úkolu, nebo vám s tím vaším snadno pomoci.

Tento přístup je přes své výhody ale i v lecčems náročnější. Zadání úkolů je třeba rozfázovat na malé části. Tyto části vám mohou zpočátku připadat až směšně malé, to ale znamená, že na to jdete dobře. Stejně jako objektový model aplikace by se měl skládat z mnoha jednoduchých malých objektů, tak i vývoj by se měl skládat z mnoha malých změn, kde každá dává izolovaně i společně smysl.

Rozfázování úkolu znamená, že je potřeba promyslet i to, jak aplikace vypadá v mezistavech. Získáte cit pro to, jaké požadavky spolu souvisí, které části úkolu jsou zásadní a které podružné. Pokud např. redesignujete část aplikace a zároveň do ní implementujete nové funkce, využijte příležitosti rozdělit tento velký projekt na dva menší – nejdřív naimplementujte a nasaďte redesign se současnými funkcemi a až poté do něj nové funkce dodělejte. Tento přístup k práci vyžaduje určitou režii navíc, ale zato si tím snížíte rizika spojená s nasazováním nových verzí aplikace na minimum. A je navenek vidět progres. Malé změny se nebojíte nasadit ani v pátek odpoledne. A pokud se to naučíte, váš vývoj bude sestávat pouze z těchto malých bezpečných změn.

The more s/w projects I see, the more I am getting convinced that most code quality guidelines have zero impact compared to feedback loops
twitter.com/pembleton

Pokud pracujete na funkcionalitě, která ještě nemá být vidět, převedete větve ve verzovacím systému na větve v kódu, tzv. feature toggles. Rozpracovanou ji tedy nasadíte do produkce, ale zpřístupníte pouze určité uživatelské roli či pod speciální URL. Stejným způsobem můžete provádět i A/B testy či postupný roll out. Počet feature toggles byste měli také ale držet na nutném minimu a jakmile je nová funkce přístupná všem, měli byste kód aplikace zase zjednodušit a feature toggle odstranit.

Pokud pracujete na něčem úplně novém, měli byste si co nejdříve ověřit užitečnost produktu. Je tedy nesmysl začínat vývoj od registračního a přihlašovacího formuláře, který je vždy stejný, ale vždy začněte od toho, co je jádrem daného produktu, co představuje jeho přínos. Pokud vám první verze bude přinášet užitek, můžete ji začít vylepšovat.

Těší mě, když vidím tyto principy aplikované i mimo softwarový vývoj. Píšete článek a nemá to konce? Rozdělte ho na více částí a ty vydávejte postupně. Píšete knihu? Vydávejte ji čtenářům po kapitolách. Zní to šíleně? Pro někoho už běžná praxe.

Další čtení: Why Continuous Deployment?, Code spiral. Doporučuju také followovat Michiela Rooka, vývojáře Phingu, který o tématu často píše a odkazuje.

Kečup nebo tatarku?

Představte si, že k vám na pohovor přijde absolvent filosofie, který se živí jako údržbář v Písku (skutečnost byla opravdu jen trošku jiná). Řekne vám, že volba filosofie byla životní omyl, ale že už půl roku se učí programovat. Nic moc, ale docela mu to myslí, tak mu nabídnete dvojnásobek jeho stávajícího platu… a za týden odepíše, že dostal lepší nabídku v jiné IT firmě. Zhruba tak dnes vypadá trh práce.