Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 7 - Proxy (zástupce)

V minulé lekci, Facade (fasáda), jsme si ukázali návrhový vzor Facade (neboli také Fasádu), který se používá k vytvoření jednotného rozhraní pro celou logickou skupinu tříd.

V tutoriálu Návrhové vzory GoF si představíme návrhový vzor Proxy (nebo také zástupce), který se používá pro řízení přístupu uživatelů k objektu, popřípadě k rozšíření nebo k zefektivnění práce s tímto objektem.

Motivace

Návrhový vzor Proxy se hodí hned v několika případech. Jeho asi nejčastější použití je zapouzdření instance jiného objektu nebo přidání pomocné funkčnosti. Proxy nám tedy umožňuje řídit přístup, ať už k celému či částečnému rozhraní objektu. Zařizuje to přes nějaký jiný zastupující objekt (proxy - zástupce, reprezentant).

Určitě jsme se už všichni setkali (nebo se určitě někdy setkáme) s případem, kdy chceme řídit přístup k nějakému objektu. Ať už čistě kvůli bezpečnosti nebo kvůli přidání další funkcionality, zefektivnění či zjednodušení ladění aplikace atd. Ve všech těchto případech se nám nejspíš bude hodit tento návrhový vzor.

Návrhový vzor

Abychom plně pochopili, kde a na co se návrhový vzor Proxy (Zástupce) používá, uvedeme si několik typických variant vzoru Proxy řešících různé situace.

Rozlišujeme čtyři zástupce:

  • vzdálený zástupce (remote proxy),
  • virtuální zástupce (virtual proxy),
  • ochranný zástupce (protected proxy),
  • chytrý odkaz (smart reference).

Remote Proxy (vzdálený zástupce)

Pokud bychom chtěli komunikovat s objektem, ale na jiném virtuálním stroji, případně na úplně jiném počítači, můžeme využít právě Remote Proxy. Jedná se o zástupce vzdáleného objektu, ve kterém je skryta veškerá komunikace.

Vzdálený zástupce zastupuje objekt umístěný někde jinde. Jeho úkolem je zprostředkovat komunikaci s tímto objektem tak, aby přes Remote Proxy mohli uživatelé komunikovat se vzdáleným (originálním) objektem, aniž by se museli starat o serverovou komunikaci (tu musí zařídit Proxy objekt). Zároveň však nesmí zakrývat komunikaci. Tj. například při selhání spojení musí vyhodit odpovídající výjimku se kterou musí uživatel počítat a případně ji vhodně zpracovat. Uživatel tak může se vzdáleným zástupcem komunikovat skoro jako s normálním objektem.

Samotná implementace Vzdáleného zástupce se dá realizovat různě. Je poněkud náročnější, protože musíme zajistit už zmíněnou komunikaci mezi dvěma objekty. Vždy však musíme při implementaci počítat s možnými selháními komunikace se vzdáleným objektem.

Virtual Proxy (virtuální zástupce)

Častý případ využití Proxy je virtuální zástupce. V naší aplikaci se může velmi často stát, že máme nějaký objekt, jehož vytváření nebo případná správa by byla náročná. Případně by to trvalo dlouho a bylo by neefektivní načítat objekt celý. Pak můžeme použít jen jeho část. Virtuální zástupce se snaží vytvořit instanci spravované třídy až když je to potřeba.

Virtual Proxy se nám i v tomto případě stará o jiný objekt (zastupuje ho). Vytvoření objektu ale přenechává až na poslední chvíli (pokud ho vůbec potřebujeme vytvořit) a chování objektu jen předstírá. Virtuální zástupce může mít navenek stejné rozhraní, ale funkčnost jen deleguje na originální objekt. Případně přidává nějakou další funkčnost a k zastoupenému objektu přistupuje či ho vytvoří jen tehdy, je-li to opravdu nutné. Typicky se může jednat o nějaký obrázek. Jeho vykreslení bude potřeba jen jednou nebo vůbec. Naše aplikace se ale zeptá na jeho rozměry nebo na další metadata (třeba i v případě, že ho později vůbec nevykreslí). Bylo by neefektivní načítat obrázek do paměti, když ho poté ani nevyužijeme.

Dalším velmi častým příkladem jsou náročnější operace. Typicky objekty načítající data z databáze. Aplikace nemusí ani zdaleka využít všechna data z daného úložiště. Můžeme definovat Proxy třídu (virtuálního zástupce), která bude načítat a vytvářet příslušný objekt, až když bude skutečně potřeba. Nebo načítat jen danou část, se kterou právě pracujeme a zapisovat jeho výsledky do cache.

Diagram virtuálního zástupce vypadá takto:

Virtual Proxy – virtuální zástupce - Návrhové vzory GoF

Protection Proxy (ochranný zástupce)

V návrhu aplikace se můžeme někdy setkat s případem, kdy by využití celého API (veřejného rozhraní) objektu mohlo mít fatální dopad. Pro příklad to může být třeba situace, kdy každý objekt má k našemu klíčovému objektu jiná přístupová práva. Nebo prostě jen potřebujeme zjednodušit rozhraní objektu, aby ho někdo neznalý našeho systému nepoužil špatně. To by mohlo mít v některých případech dokonce fatální následky.

V obou výše zmíněných případech si definujeme novou Proxy třídu, která si spravuje instanci objektu. Navenek ale nabízí jen podmnožinu metod objektu, který zastupuje. Můžeme tak ovlivnit, ke kterým metodám cílového objektu bude mít uživatel přístup a ke kterým nikoli. V některých případech, kdy nám jde jen o omezení rozhraní, ho lze nahradit jednoduchým rozhraním. To je sice efektivnější, ale zároveň méně bezpečné. Uživatel má v tomto případě stále přístup k celému objektu pouze pod zjednodušeným rozhraním. Může si tak celkem jednoduše zjistit, o jaký objekt jde.

Smart Reference (chytrý odkaz)

Pokud chceme doplnit komunikaci s objektem o nějaké další akce, vhodné třeba pro zefektivnění a zrychlení celého chodu aplikace, je Chytrý odkaz (smart reference) ten návrhový vzor, který hledáme.

Typicky se používá pro uložení trvalého (persistentního) objektu do paměti. Takový objekt pak můžeme chytře uchovat mezi jednotlivými požadavky na naši aplikaci právě pro zefektivnění či zrychlení aplikace. Takový chytrý zástupce si například může po vykonání požadavku nastavit limit, po kterém se ukončí spojení se vzdáleným serverem nebo se vymaže z paměti. Pokud se po daný limit nepřipojí žádný klient, chytrý odkaz se při dalším připojení načte jednoduše znovu do paměti nebo znovu otevře připojení ke vzdálenému serveru. Toho se například využívá při uchovávání spojení s databází či s jiným vzdáleným serverem.

Jako chytrý odkaz se chová také každý virtuální zástupce, který jsme si vysvětlili výše. Ten se totiž také musí sám rozhodovat, kdy přistoupí k originálnímu objektu a kdy si naopak pomůže sám. Například načte hodnoty z cache, zjistí pouze metadata místo načtení celého média a podobně.

V další lekci, Decorator (dekorátor), si ukážeme návrhový vzor Decorator. Vzor dovoluje přidat funkcionalitu třídě za běhu programu a přitom od ní nedědit.


 

Předchozí článek
Facade (fasáda)
Všechny články v sekci
Návrhové vzory GoF
Přeskočit článek
(nedoporučujeme)
Decorator (dekorátor)
Článek pro vás napsal Drahomír Hanák
Avatar
Uživatelské hodnocení:
43 hlasů
Autor v současné době studuje Informatiku. Zajímá se o programování, matematiku a grafiku.
Aktivity