Proxy 1
Proxy – úvod Problém Klient má přístup k nějakému objektu Potřebujeme tento přístup ošetřit Kontrola přístupu Vzdálený přístup Cachování Load on demand Nechceme přidat práci klientovi ani objektu Proxy Jednoduchý, ale efektivní vzor Spravuje použití a přístup ke zdrojům Šetří pamět, kontroluje přístup
Proxy – motivace Příklad ze života Šek nebo kreditní karta Použití Místo peněz Prostředek k přístupu k penězím Reální subjekt Bankovní účet Proxy kontroluje a spravuje přístup k objektu, který „ochraňuje“
Proxy Proxy poskytuje bariéru mezi klientem a reálnou implementací
Proxy – struktura UČASTNÍCI Subject Proxy RealSubject Client Interface, ke kterému má klient přístup Společné rozhraní pro Proxy a RealSubject Proxy Má přístup k RealSubject Předává mu requesty, kontroluje přístup Zná některé jeho vlatnosti RealSubject Skutečný objekt Client Není schopen přistupovat k RealSubject, aniž by prošel přes Proxy
Proxy – použití Kdy ho použít Objekty leží v rozličných adresových prostorech (RP) Možnost zrychlení aplikace (VP) Objekt je nutno vytvořit na dotaz Oddálení načítání zdrojů dokud nejsou potřeba Usnadňuje přístup k pamětově náročným položkám jako obrázky nebo grafika Nutná kontrola přístupu k původnímu objektu (PP) Je vyžádána dodatečná funkcionalita při přístupu k objektu (SP, PP) 6
Proxy - typy Virtual proxy Remote proxy Synchronized proxy Zastupuje objekt - má stejné rozhraní, ale funkčnost deleguje na jiný objekt Vytváření objektů až v případě potřeby („load on demand“) Remote proxy Lokální zástupce vzdáleného objektu Řeší komunikaci s objektem Middleware: C# Remoting, XML/SOAP, ... Synchronized proxy Synchronizace přístupu ke skutečnému objektu Protection proxy Kontrola či omezování přístupů ke skutečnému objektu Smart pointers/reference Náhrada běžných ukazatelů či referencí Počítání referencí a automatické odalokování (C++ std::shared_ptr) Načítání do paměti při první dereferenci 7
Virtual proxy – příklad použití Prohlížeč obrázků Seznam všech obrázků ve složce a jejich zobrazení Špatný přístup – získáme seznam obrázků a všechny fotky nahrajeme do paměti Lepší řešení – zobrazení fotky na vyžádání (load on demand) Ušetříme práci a paměť – nezobrazené fotky se vůbec nenačtou Elegantní realizace řešení – PROXY
Virtual proxy – příklad Real object interface IImage { void DrawImage(); Size GetSize(); }; Interface class RealImage : IImage { public RealImage(fileName) { // skutecne nacitani obrazku // pomale loadImage(fileName); } public void DrawImage() { // renderovani obrazku public Size GetSize(fileName) { return new Size(data.cols, data.rows); }; Proxy public class ImageProxy : IImage { private string fileName; private Image image; private Size size; public ImageProxy(string fileName) { this.fileName = fileName; } public void DrawImage() { GetImage().DrawImage(); public Size GetSize() { if (size.IsEmpty) size = GetImge().GetSize(); return size; private Image GetImage() { if (image == null) image = new RealImage(fielName); return image; } } IImage CreateImage(string fileName) { return new ImageProxy(fileName); } IImage img1 = CreateImage(“img1.png”); IImage img2 = CreateImage(“img2.png”); img1.showImage(); // z disku img1.showImage(); // z paměti img2.showImage(); // z disku
Protection proxy – příklad Vytvoření neměnitelné kolekce Řešení problému absence const v C#: Omezení rozhraní Protection proxies (wrappers) public interface ICollection<T> { bool Contains(T item); bool Add(T item); //.... } public class ReadOnlyCollection<T> : ICollection<T> { private ICollection<T> c; public ReadOnlyCollection(ICollection<T> c) { this.c = c; } public bool Contains(T item) { return c.Contains(item); } public void Add(T item) { throw new NotSupportedException(); } //... } public static ICollection<T> AsReadOnly(this Collection<T> c) { return new ReadOnlyCollection<T>(c); // vytvoření seznamu List list = new List<int>(); // příprava dat apod. // nyní se vytvoří neměnná kolekce ICollection<int> c = list.AsReadOnly(); 10
Synchronization proxy – příklad Standardní kolekce nejsou v C# thread-safe Umožňuje vyšší rychlost Volitelné řešení: synchronization proxies (wrappers) Myšlenkově identické s předchozí ReadOnlyCollection public class SynchronizedCollection<T> : ICollection<T> { private ICollection<T> c; public SynchronizedCollection(ICollection<T> c) { this.c = c; } public bool Contains(T item) { lock(c) { return c.Contains(item); } } public bool Add(T item) { lock(c) { return c.Add(item); } //... public static ICollection<T> MakeThreadSafe(ICollection<T> c) { return new SynchronizedCollection<T>(c); // typický příklad ICollection<string> l = MakeThreadSafe(new List<string>()); 11
Remote proxy – C# Remoting public interface IComputation { public int Execute(); } public class Computation : MarshalByRefObject, IComputation { public int Execute() { // operace na serveru } // server var channel = new TcpServerChannel(5000); ChannelServices.RegisterChannel(channel, true); RemotingConfiguration.RegisterWellKnownServiceType( typeof(Computation), "computation", WellKnownObjectMode.SingleCall); // klient var channel = new TcpClientChannel(); ChannelServices.RegisterChannel(channel, true); IComputation remoteObject = (IComputation) Activator.GetObject( typeof(IComputation), "tcp://localhost:5000/computation"); remoteObject.Execute(); 12
Proxy +/- Výhody Nevýhody Zjednodušení cílového kódu Zapouzdření optimalizací a strategie přistupování k objektu Oddělení administrativního kódu od funkcionality Transparentní a snadný návrhový vzor Nevýhody Snižení efektivity vrstva navíc, reference navíc ne vždy to vadí (přístup k externím datům je mnohem pomalejší) Tvorba sady proxy pro větší subsystém může být zdlouhavá Řešení: automatizace pomocí např. Reflection – opět citelné zpomalení Klient o proxy vrstvě jakoby neví nezná možné vedlejší účinky (připojování k síti, náročné operace) 13
Proxy – související NV Adapter Decorator Také tvoří mezivrstvu Jiný účel Adapter: rozdílné rozhraní, stejná funkčnost Proxy: stejné rozhraní, rozdílná funkčnost Decorator Podobná struktura, ale jiný účel - přidává funkčnost Musí po celou dobu běhu držet fyzickou instanci skutečného objektu U proxy ještě nemusí existovat nebo může být např. na jiném počítači 14