Návrhový vzor: 1. Singletonový vzor

Co je kreační návrhový vzor?

(26. prosince 2020)

Kreativní návrhové vzory se zabývají tvorbou nebo klonováním nových objektů třídy. Klonování nastane, když již existuje podobný druh objektu, a místo vytvoření nového objektu klonujeme existující.

Různé způsoby vytváření objektů budou mít velký vliv na vyřešení problému. Různé jazyky proto ovlivňují, jaké vzory je možné použít.

Singleton Pattern

Singleton pattern se používá, když požadujeme pouze jednu instanci třídy. Například vytvoření připojení DB v aplikaci, tisková fronta tiskárny, použití protokolovacích nástrojů, protože vyžadují spoustu prostředků. Ve všech těchto případech, pokud existuje více instancí, vytvoří se zmatek i nekonzistence.

Tento vzor se používá, když je instance sdílená a globálně přístupná napříč aplikací. Zajištění toho, aby byl přístup ke sdíleným zdrojům bezpečný, je jedním z velmi dobrých příkladů toho, kde může být tento druh vzoru životně důležitý. záměrem vzoru Singleton je poskytnout globální přístup ke třídě, která je omezena na jednu instanci.

Podívejme se, jak je objekt vytvořen

public class DummyClass{ DummyClass(){}
}DummyClass dc = new DummyClass(); //every time when this line is called a new object of DummyClass is created

Nyní, kdykoli je potřeba objekt DummyClass, zavolá se jeho konstruktor a vytvoří se objekt. Toto se nazývá Eagerova inicializace.

Ale v singletonovém vzoru vyžadujeme pouze jednu instanci třídy. Řekněme, že pokud je připojení DB již nastaveno, nemusíme vytvářet nové připojení DB a měli bychom použít již existující připojení. Pojďme se podívat, jak toho dosáhnout.

Zde jsme omezili rozsah konstruktoru na samotnou třídu. Chcete-li tedy vytvořit objekt této třídy, je třeba volat statickou metodu třídy getDBConnection (). Poté zkontroluje, zda je objekt dbConnection null, poté vytvoří nový objekt připojení a vrátí, jinak vrátí existující objekt připojení.

Tento příklad ukazuje koncept líná inicializace . To znamená, že nevytváříme objekt třídy, pokud to není skutečně nutné. Proto je tento program efektivnější z hlediska zdrojů.

Existují kompromisy s principem návrhu Singleton. Pokud je spuštěno více výpočetních vláken, mohou nastat problémy způsobené vlákny při pokusu o přístup ke sdílenému jednomu objektu.

Problémy ve výše uvedené implementaci

Nyní je možné, že dva vlákna současně volají metodu getDBConnection a objekt ještě není vytvořen. Pro obě vlákna bude objekt dbConnection null a oba se pokusí vytvořit novou instanci a místo toho ji použít. Je proto velmi důležité zajistit, aby jedno vlákno mohlo přistupovat k getDBConnection najednou, aby se nevytvořilo více instancí.

Chcete-li dosáhnout vlákna -safe třídou singleton je synchronizace globální metody přístupu, takže tuto metodu může současně provádět pouze jedno vlákno.

K tomuto synchronizovanému bloku kódu může najednou přistupovat pouze jedno vlákno

Možná si myslíte, že problém je nyní vyřešen. Ale bohužel ne! Abychom vynutili vlastnost singleton, umístili jsme zámek na statickou metodu getDBConnection, ale současně jsme ohrozili její výkon. Když je objekt již vytvořen, pak také musí více vláken čekat na získání existující instance tohoto objektu. Můžeme udělat něco lepšího? Podívejme se.

Jak je zřejmé, zámek je vyžadován pouze v případě, že je instance nulová, aby různá vlákna nevytvářela více instancí. Můžeme tedy do podmínky if vložit synchronizovanou podmínku, kde kontrolujeme, zda je instance nulová nebo ne, a přidat dvojitou kontrolu, abychom vyloučili scénáře více instancí.

Při skutečném použití lze singletonový vzor implementovat různými způsoby. Pouze definuje základní účel, kterému tento vzor slouží, ale implementace kódu se může lišit.

To je z mé strany vše. Doufám, že je nyní jasné, kde, kdy a jak použít singletonový vzor. Pro lepší pochopení si můžete přečíst knihu Katalog designových vzorů Gang of Four.

Máte-li jakékoli pochybnosti, dejte mi prosím vědět v komentářích níže. Pokud se vám tento blog líbí, sdílejte ho mezi svými přáteli. Šťastné softwarové inženýrství!

Část 2: