Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Co je špatně se Service Locatorem?

17.56 - 16. dubna 2012 | Moje práce

Service Locator je obecný návrhový vzor, který dodává jeho uživatelům instance požadovaných služeb. Existuje několik variant implementace tohoto vzoru a dokonce jsou od něj odvozeny i další specifcké vzory.

Singleton

Nejjednodušší implementaci service locatoru zná asi každý, kdo kdy s návrhovými vzory koketoval – je jím starý známý Singleton! Krom toho, že Singleton svou vnitřní implementací zajišťuje garantovaný lifetime instance, tak tuto instanci i poskytuje – typicky pomocí statické vlastnosti Instance v horších jazycích pak funkcí getInstance().

Abstract Factory

Další z častých implementací service locatoru je Factory, jde o další konkrétnější odvozeninu vzoru, která má semantiku nejen instance dodávat, ale i vytvářet. V důslednějších variantách má factory na starosti i řádnou destrukci vytvořeného objektu. Já to nazývám „šrotovným“. :) Factory většinou vytváří nové instance pomocí metody Create() nebo nějaké její variace.

Generický Service Locator

Další častou implementací je obecný service locator v mnoha aplikacích/fra­meworcích taky přezdívaný jako Registry nebo Kernel a podobně. Základním rozhraním většiny IoC kontejnerů je právě takovýto service locator. Většinou instance dostaneme zavoláním metody GetInstance() nebo Resolve().

Jak vidíte, vzory jsou to známé, celkem běžně užívané, narážíme na ně denně. Tak co je špatně? Proč někdo používá označení Service Locator pejorativně?

Usage pattern

Service locator totiž není jen návrhovým vzorem, ale i vzorem užití. A tady narazíme na jádro pudla. Vezměme si mou oblíbenou ukázku se Singletonem. Tento vzor jal se býti častován anti-patternem. Je to snad, kvůli tomu, že by to byl špatný návrhový vzor? Myslím, že ne. Tento vzor se spojil v lidských hlavách se vzorem užití, který je špatný!

Ruku na srdce, kolikrát ve svém kódu voláte, třeba HttpContext.Current místo toho, abyste si ho nechali injektovat konstruktorem?

public class SomeWebFoo {
  public void DoWork() {
    // code
    if (HttpContext.Current.IsDebuggingEnabled) {
    // code
  }
}

public class BetterWebFoo {
  readonly HttpContextBase httpContext;

  public BetterWebFoo(HttpContextBase httpContext) {
    this.httpContext = httpContext;
  }

  public void DoWork() {
    // code
    if (httpContext.IsDebuggingEnabled) {
    // code
  }
}

První třída používá Service Locator usage pattern, druhá inversion of control. V prvním případě skrytě přistupujeme přes statickou vlastnost (globální proměnná) k instanci konkrétního typu. Druhá třída svou závislost veřejně deklaruje, ale je jí navíc jedno, jaký konkrétní typ dostane – závisí pouze na abstrakci. Proč je první třída ve většině případů horší nechám už na vás. Určitě na to přijdete. ;)

Texy.js - první dojmy

09.37 - 11. března 2012 | Moje práce

Posledních pár týdnů jsem koketoval s myšlenkou zase se pokusit o vlastní implementaci Texy!, abych jí mohl pohodlnějš používat na svých projektech. Texy.net sice funguje, ale má své neduhy. Texy WS jsem používal na několika projektech, ale zas jí chybí pořádné API. Proto jsem chtěl něco nativního. Portovat to ale do C# už se mi nechtělo. Rozhodoval jsem se mezi implementací v F# nebo v JavaScriptu.

Vyhrál JavaScript

JavaScript je dneska všude a ať budu svůj další projekt chtít psát v čemkoli je velká pravděpodobnost, že Texy.js využiju. Tak, jako před lety bylo pro původní Texy! PHP jasnou volbou – PHP bylo na většině serverů, dnes je jasnou volbou JavaScript. Běží jak v browseru, což může mnoho věcí, co se dají s Texy! dělat, zpříjemnit, tak na serverech – ať už v podobě Node.js nebo implementací pro VM.

JavaScript je navíc jazyk, který dokáže psát/číst kde kdo. Je velká šance, že se do otevřeného vývoje zapojí další lidé, kteří nejsou nutně sběhlí v F# nebo dotnetu. Navíc je JavaScript celkem pěkným jazykem, ikdyž si to lidé často nemyslí. Rozhodl jsem se psát to v ECMA Scriptu 5, řídit vývoj pomocí TDD a držet čistý kód. Zároveň se nebojím toho, že někdo objeví moji chybu, proto když píšu tak i často pushuju. Čím dřív někdo chybu objeví, tím líp. Chyby děláme všichni, důležité je na to přijít co nejdříve.

JavaScript není objektovým jazykem, ale zato je slušným funkcionálním jazykem, proto v kódu zatím moc typů nenajdete, spíš hodně funkcí. Měla by to být taková skládačka jednoduchých a čistých funkcí. Texy.js chce být minimalistická a neexpanzivní.

Borkův boj

Od začátku dostávám od @borekb spoustu dotazů, ale vzhledem k našim opačným biorytmům se moc nestřetáváme, abych mohli vést kvalitní dialog. :) Tady se pokusím osvětlit několik jeho dotazů.

Texy.js píšu ve WebStormu a pro běh testů požívám JsTestDriver, který je součástí poslední verze. Projekt zatím není moc contributors friendly, protože jsem na něm trávil zatím jen pár hodin minulý víkend. A v tomto omezeném čase jsem chtěl mít připravenou nějakou funkčnost nad kterou se dá dál stavět a nezaobírat se věcma, jako je chybějící README s návody jak si pustit testy. IMO by toho měl být každý vývojář schopnej – Google je náš kamarád. Časem, až bude projekt víc stable, se tyhle věci jistě doplní. Už jsem se zmiňoval, že přijímám příspěvky? ;) Ano i README je hodnotným příspěvkem!

Texy.js píšu tak, že si čtu Texy! na githubu a přemýšlím, co tím chtěl básník říct. Když na něco příjdu, napíšu na to test a snažím se ho naimplementovat. Ikdyž mám jiný názor na to, jak by měl vypadat srozumitelný kód a jak dělat návrh, snažím se držet původních myšlenek a produkovat na 99,999 % stejné výsledky. Ta mírná odchylka není zaokrouhlovací chybou, jen se mi tam nechce cpát ten reklamní komentář.

Texy! vnitřně pracuje s UTF-8, využívá speciální znaky apod. Chci co nejvíc použít myšlenky (a někdy i kód) z původní implementace, proto Texy.js taky vnitřně pracuje v UTF-8. JavaScript nic pořádnýho na práci s různými kódováními nemá, proto jsem zaintegroval kus chytrého kódu, který převádí UTF-16 na UTF-8 a zase zpátky. Jo, není to moc clean code. Je to dost low level, ale taková už práce s kódováním je…

Odpověď na otázku, proč Texy.js nahrazuje A se stříškou je snadná: Soft Hyphen (alias ­) se v UTF-16 zapisuje jako \u00AD, ale v UTF-8 jsou to dva byty \xC2\xAD.

To je prozatím odemě vše. Pokud máte dotazy nebo názory, nebojte se je napsat do komentářů. Pokud máte nápady na vylepšení, nebojte se udělat fork a poslat pull-request. Pokud bude dobrý, zaintegrujeme. Pokud ne, určitě vám napíšu, co se mi nezdálo. :) Pokud máte zájem o nějakou featuru, pošlete pull-request s padajícím testem.

Tři přikázání TDD

14.29 - 25. prosince 2011 | Moje práce

Volně přeloženo z knihy The Clean Coder

  1. Nenapíšeš řádky produkčního kódu, aniž bys měl padající test.
  2. Nenapíšeš řádky testovacího kódu, pokud již nejsou aktuální řádky schopné projít (nezkompilovatelný kód také neprojde).
  3. Nenapíšeš řádky produkčního kódu, které nejsou nezbytně nutné, aby prošel aktuálně padající test.

Strava pro vaše oči, uši a mozek

09.26 - 25. prosince 2011 | Moje práce

Už je tomu nějakej ten pátek, co jsem Marianovi slíbil, že napíšu článek s videama, o kterých si myslím, že jsou velmi dobrá na procvičování funkcionálního programování a abstraktního myšlení vůbec. Tak tady jsou:

MinLINQ

První z nich ukazuje implementaci LINQ operátorů pomocí funkcionální kompozice tří základních operátorů Ana, Bind a Cata:

Rx pod kapotou

Další se zabývá velice zajímavými koncepty asynchroního a konkurenčního přístupu v reaktivních extenzích:

Design programovacích jazyků

Poněkud starší video o tom, jak se vaří programovací jazyky, s lidmi, kteří je opravdu navrhují. Erik Meijer je jedním z mistrů Haskellu a mimo jiné i mozkem za LINQ a Rx ve světě dotnetu. Gilad Bracha je toho času součástí týmu tvořícího Dart. A Mads je v teamu tvořící C#. Takže samí zajímaví lidé se zajímavými pohledy na jazyky.

Fukcionální programování

Další video s Erikem „you know“ Meijerem. :) Také staršího data, ale to na kvalitě neubírá, představuje koncepty funkcionálního programování v dotnetu.

A komu to přijde málo a má chuť (a čas) se do funkcionálního programování opravdu obout, tak doporučuju celou 13 dílnou serii Erikových lekcí. Často jsou ukázky v Haskellu, ale tady jde o koncepty a nakonec není od věci podívat se i na jiný programovací jazyk, že.

K čemu vlastně TDD?

13.09 - 18. prosince 2011 | Moje práce

Na proběhnuvším CodeRetreatu jsme se a pány Kolmanem a Augustýnem balivi o tom k čemu vlastně je TDD, jaký má přínos?

Michal argumentoval tím, že dělá testable design a testy píše potom a že je s tím cajk, že nevidí důvod, proč dělat TDD. S Danem jsme nahazovali okřídleané pravdy o výhodách TDD, které Michal zašlapal. A tak jsme nenašli správnou argumentaci. A já o tom musel přemýšlet. Přece tam musí být nějakej zásadní rozdíl!

A on je. Ta největší devíza TDD je iterativní přístup k vývoji. Pakliže se držíte nějaké agilní metodiky a jednou za iteraci máte funkční produkt, který může jít potenciálně do produkce. S TDD jste v takovém stavu takřka každou chvíli (po dokončení kolečka Red-Green-Refactor). Kdykoli za vámi někdo přijde, že chce vidět jak na tom jste, tak nemusíte říkat „těd to nejde, zrovna mám něco rozdělanýho a nefunguje to.“ S TDD vám aplikace funguje takřka pořád. Sice nemá všechny požadované vlastnosti, ale je funkční.

Trénujete na Code Retreat?

09.19 - 26. listopadu 2011 | Moje práce

Již za týden se koná akce, do které jsem tak trochu namočený, Global Day of Code Retreat. My se snažíme připravit jedno místečko v Praze.

Ačkoli má akce za cíl vás vytrénovat v lepší vývojáře, je dobré abyste na něj přišli trochu připravení. :) Určitě si přečtěte pravidla problému, který se bude celý den znova a znova implementovat. Ale nezůstaňte pouze u čtení, zamyslete se nad tím, jak danou úlohu naimplementovat. Nebojte se a jděte ještě dál a vážně tu vaši ideu i zhmotněte!

Dalším krokem jak se na akci připravit, je zacvičit si nějakou tu katu v kódování. Zkuste třeba oblíbenou bowling game nebo string calculator. Procvičíte si tak TDD i nástroje, které budete používat.

O vymýšlení kola

13.48 - 15. listopadu 2011 | Moje práce

V pátek jsem si utvítl, že „Psát virtuální distribuovanej file systém je challenge.“ a hned jsem dostal reakce, že jsem další v řadě a že znova vymýšlím kolo a další parafráze mých výroků.

Jak to tedy je? :)

Challenge pro vás

Ukažte mi implementaci VirtualPathProvideru, který má správně vyřešené cachování a škáluje přes více než jeden webový front-end.

Když se vám to povede, veřejně mě můžete prohlásit za hlupáka, který neumí hledat a znovu vynalézá kolo. Když se vám to nepovede, můžete se mě snažit uplatit, abych vám prozradil pikantní podrobnosti.

Refaktoring

09.31 - 23. července 2011 | Moje práce

Poslední dobou se mi velmi často stává, že narážím na hlášky typu “od devíti refaktoruju a furt to nemá konce,” “refaktoring mi zabere asi tři dny, udělej mi na to task do backlogu” nebo „refaktoroval jsem to a nějak to přestalo fungovat.“ Tohle všechno jsou lži, ať už plynoucí z neznalosti, co to je refaktoring nebo trendy nadužívání tohoto slova v nepatřičných situacích.

Co je to refaktoring?

Refaktoring je pojem, který je definován poměrně přesně. Je to krátká atomická operace nad kódem, která nemění jeho funkci, pouze strukturu. Z definice jasně vyplývá, že věty z úvodu jsou lži.

Refaktoring patří k základní hygieně čistého kódu. Měli byste ho používat neustále. Není to věc, kterou byste měli zahrnovat do plánů jako něco extra, podobně jako testy, jsou jejich nedílnou součástí. A sluší se je zahrnout do časových odhadů jednotlivých úkolů. Ne však jako samostatné úkoly!

Říkám refaktoring, myslím redesign

Refaktoring se stal trendy pojmem. Manažeři mu nerozumí a programátoři se sním furt ohánějí. „Proč ti to trvalo tak dlouho?“ „Ještě jsem musel udělat refaktoring tohodle a tamtoho.“ Jenže jak jsme si řekli v definici, refaktoring je krátká operace! Velmi krátká, pokud máte dobré nástroje, netrvá více než pár stisků kláves. Řádově trvá jednotky sekund.

Refaktoring má navíc tu vlastnost, že i když děláte velkou sérii – provádíte redesign – můžete kdykoli přestat a aplikace stále funguje. Ano, je to tak. Opět to vyplívá jasně z definice. Pokud ne, děláte jenom redesign.

Redesign

„Musíme to přepsat.“ Ta slova nemají manažeři rádi. Znamená to spoustu promarněných (z jejich pohledu – my přece víme, že se to musí udělat a že se to vrátí) hodin/dní (někdy i měsíců a let) práce. A tak se místo redesignování začalo „refaktrovat.“ Přestaňme si lhát. I když třeba během redesignu použijeme nějaký ten refaktoring, pořád je to redesign. Redesignovat můžeme přinejmenším dvěma způsoby:

  1. Hurá redesign, kdy se původní kód zahodí a napíše se to znova a občas se něco z toho původního copy&pastene. Tohle se často dnes nazývá refactoring. A většinou z toho vypadne podobná sračka, jako byla před tím, jen bude mít jiný tvar.
  2. Můžeme postupně refaktorovat a časem se dostat k lepšímu designu. Ale nezapomínejte, vždycky tenhle proces můžete přerušit a aplikace funguje. Stačí, že změny jsou good enough. Váš kód nikdy nebude dokonalý.

Nejsem schopný dopsat článek o Continuous Integration

07.50 - 14. června 2011 | Moje práce

Je třeba si to přiznat. Nedokážu vše. Např. nedokážu odpřednášet nebo napsat článek o Continuous Integration. Je to škoda, protože si myslím, že toho o tom víc celkem dost, dlouho to praktikuju a tak, ale prostě je nad moje síly dát tomu lepší formu než konzultaci či workshop.

Každopádně jsem nad tím článkem strávil spoustu času a byla by škoda, kdyby se nikdy nedostal k očím dychtivých čtenářů. Proto jsem se rozhodl, že článek uvolním pod licencí Creative Commons, nabídnu ho ke stažení, těm co jim nevadí špatná forma. A pokud se najde dobrá duše, která se rozhodne článek dopsat/zeditovat a publikovat na zdrojáku, nechť tak učiní. Jen musí zachovat licenci a uvést mé jméno jako spoluautora. :) Toť pro dnešek vše.

Jo a tady je ten zázrak.

Přepínání featur a větvení abstrakcí

09.01 - 11. června 2011 | Moje práce

Správa několika verzí aplikace vždy přináší komplexitu, která zvyšuje náklady na vývoj i na údržbu. Běžnou praktikou je, že se zdrojové kódy v repositoři větví (branching) v určitých Milestonech, které se potom stabilizují a po releasu udržují, zatím co v hlavní větvi (trunk, main) se pokračuje ve vývoji. S příchodem DVCS se rozmohlo lokální větvení po featurách, čímž se různorodost verzí aplikace ještě víc rozrostla.

Naproti tomu tu máme agilní praktiky jako je Continuous Integration a Continuous Delivery, které nám říkají, že všichni commitují často do hlavní větve, čímž se předchází integračním problémům. Continuous Delivery navíc říká, že „aplikace má pouze jedinou verzi – tu aktuální.“ Jak to ale udělat, když rozsah některých featur přesahuje rámec sprintu? Ano, můžeme udělat feature branch, ale tím porušujeme pravidlo, že všechno je v hlavní větvi! Poslední verze TeamCity sice podporuje workflow s personal buildy vůči feature branchi, ale to je integrační smell.

Branch by abstraction

Existuje lepší řešení! Proč nevyužít technik OOP jako je polymorfismus a IoC? Je to krapet složitější, než branchování v repositoři, ale zároveň nás to donutí zamyslet se nad architekturou aplikace a ve výsledku bude IMO lepší. V aplikaci můžeme mít nekolik implementací požadované funkcionality, které jsou následně injektovány na základě konfigurace. Některé mohou být stabilní a používat se v produkčním prostředí, zatímco u vývojáře poběží aktuální edge implementace, na které se pracuje.

Takže implementaci kódu máme vyřešenou, ale jak na to v uživatelském rozhraní?

Feature toggles

Pokud naše UI není přímo generováno aplikačním kódem, kde by se dala využít předchozí technika, musíme sáhnout po nečem trochu jiném – přepínačích featur. Začneme tím, že každá feature má svůj jedinečný identifikátor. Každá featura je zařazena do uživatelského rozhraní s tímto identifikátorem a na základě konfigurace je opět rozhodnuto, zda dojde k jejímu zobrazení uživateli nebo ne. Takto se dají nejen snadno odříznout nestabilní featury z produkčního prostředí, ale dá se to využít i k takovým věcem, jako je A/B testování, čí postupné spouštění featury do produkce, jak to znáte z oblíbených služeb jako je Facebook nebo Twitter. ;)