Proxy (zástupce)

Návrhové vzory Proxy (zástupce)

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 přes nějaký jiný zastupující objekt (proxy - zástupce, reprezentant).

Motivace

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. Tyto varianty jsou rovněž uvedeny v GoF.

Remote Proxy (vzdálený zástupce)

Pokud bychom chtěli komunikovat se stejným 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 s uživateli.

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říp. by trvalo dlouho a bylo by neefektivní načítat ho celý, když pak použijeme 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á. Tj. navenek může mít 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 tř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á je bude načítat a vytvářet příslušný objekt, až když bude skutečně potřeba, načítat jen danou část, se kterou právě pracujeme, zapisovat jeho výsledky do cache, abychom je nemuseli načítat pořád znovu atd.

Virtual Proxy – virtuální zástupce

Virtual Proxy - virtuální zástupce

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ě, což 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, ale navenek definuje 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, což je efektivnější, ale zároveň méně bezpečné. Uživatel v tomto případě má pořád 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ř. 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 využívá například 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ř načte hodnoty z cache, zjistí pouze metadata místo načtení celého média apod.)

Závěrem

Návrhový vzor Proxy patří mezi návrhové vzory uvedené v GoF. Jde tedy o "pravý" návrhový vzor. Většinou se používá pro zapouzdření aplikace, ale lze ho použít i pro zlepšení funkčnosti (např. zefektivnění, zrychlení aplikace atd.). Rozlišujeme čtyři zástupce: vzdálený zástupce (remote proxy), virtuální zástupce (virtual proxy), ochranný zástupce (protected proxy) a chytrý odkaz (smart reference).

Kde se dočtu víc?

  • [1] PECINOVSKÝ, Rudolf. Návrhové vzory: 33 vzorových postupů pro objektové programování. Brno: Computer Press, a.s., 2007. ISBN 978-80-251-1582-4.
  • [2] Proxy pattern. Wikipedia [online]. 2009, 2013 [cit. 2013-07-29]. Dostupné z: http://en.wikipedia.org/…roxy_pattern

 

  Aktivity (1)

Článek pro vás napsal Drahomír Hanák
Avatar
Autor v současné době studuje Informatiku. Zajímá se o programování, matematiku a grafiku.

Jak se ti líbí článek?
Celkem (4 hlasů) :
55555


 


Miniatura
Předchozí článek
Servant (Služebník)
Miniatura
Všechny články v sekci
Návrhové vzory
Miniatura
Následující článek
Object pool (fond objektů)

 

 

Komentáře

Avatar
Kit
Redaktor
Avatar
Kit:

"kontrolovat přístup" - to je nějaký anglikanismus. Správně tam patří "Řídit přístup" neob "Ovládat přístup". Špatně jsi to přeložil.

Odpovědět 31.7.2013 10:04
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Drahomír Hanák
Tým ITnetwork
Avatar
 
Odpovědět 31.7.2013 10:11
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.