čtvrtek 11. března 2010

Pryč se Singletony

Gang of Four odhalil na světlo světa katalog návrhových vzorů, díky kterému se do širokého povědomí dostaly přístupy k řešení typických úkolu v objektovém programování. Mezi nejznámější návrhové vzory patří bezesporu Singleton, řešící existenci pouze jedné instance dané třídy. Nevím jestli je jeho popularita zapříčiněna tím, že jej každý pochopí a nebo tím, že jej každý potřebuje (nebo si to alespoň myslí), každopádně singletony najdeme v každém kódu. Bohužel ve skutečnosti jakékoliv použití Singletonu sebou nese značná rizika a nevýhody. Pro mě osobně testování a svázání objektů. Pravda, není to chyba vzoru jako takového, ale spíše jeho zneužívání na nesprávných místech.

Pojďme zkusit najít zakopanou kostra pudla. Singleton ze své podstaty drží nějaký kontext, ostatně proto jej zavádíme. Dobrá rada na začátek. Pokud najdete v kódu singleton, který nedrží kontext, pak máte skvělou příležitost tenhle singleton (chování) odstranit, protože je zbytečný. Skrze kontext se dostáváme k jiným částem systému (service locator), to mohou být například nacacheovaná data, pool připojení k databázi a tak dále. To stále ještě není problém, ten nastane ve chvíli, kdy začnete singletony nořit do sebe. Z aplikace se totiž stane jedna velká drátovaná koule bahna.

Známe problém, ale známe řešení? Podle mých zkušeností je nejlepším řešením obrácená kontrola realizovaná pomocí dependency injection. Dependency injection neelimujeuje singletony jako takové, ale umožňuje je přesunout pryč z aplikačního kódu do vrstvy frameworku. To je přesně o co tu běží. V čistě napsané aplikaci by neměl být použitý jiný singleton než ten představující entry point do vlastní aplikace. Typickým příkladem je singleton frameworku, kterému se předá řízení při přijetí HTTP požadavku. V případě desktopové aplikace je to singleton představující service locator, přes který se získávají jednotlivé controllery.