Proxy Proxy Popis Klient má přístup k nějakému objektu Potřebujeme tento přístup ošetřit, aniž bychom přidělali klientovi práci Kontrola přístupu Vzdálený přístup Cachování Load on demand.
Download ReportTranscript Proxy Proxy Popis Klient má přístup k nějakému objektu Potřebujeme tento přístup ošetřit, aniž bychom přidělali klientovi práci Kontrola přístupu Vzdálený přístup Cachování Load on demand.
Proxy
Proxy
Popis
Klient má přístup k nějakému objektu Potřebujeme tento přístup ošetřit, aniž bychom přidělali klientovi práci Kontrola přístupu Vzdálený přístup Cachování Load on demand
Struktura
ÚČASTNÍCI
Subject Společné rozhraní RealSubject Skutečný objekt Proxy Stejné rozhraní jako real subject M á pointer na real subject, předává mu requesty, kontroluje přístup ...
Motivace
Příklad
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) E legantní realizace řešení –
PROXY
};
Prohlížeč obrázků
Proxy { public class ImageProxy : Image String fileName; Image proxifiedImage; } public ImageProxy(String fileName) { this.fileName = fileName; } public void ShowImage() { if (proxifiedImage == null) proxifiedImage = new RealImage(fileName); proxifiedImage.showImage(); } public Size GetSize() { return HeaderInfo.LoadSize(fileName); ImageProxy img1 = new ImageProxy (“img1.png”); ImageProxy img2 = new ImageProxy (“img2.png”); Console.WriteLine(img2.GetSize()); Img1.ShowImage(); Interface { Interface Image void ShowImage() ; Size GetSize(); }; RealObject { class RealImage implements Image public RealImage(fileName) { // skutecne nacitani obrazku z disku // pomale loadImage(fileName); } } public void ShowImage() { // renderovani obrazku public Size GetSize(fileName) { return new Size(data.cols , data.rows); } };
Proxy - typy
Virtual proxy
V ytváření objektů až v případě potřeby („
load on demand “
) T ransparentní provádění optimalizací (
Cache proxy
,
Copy-on-write proxy
)
Remote proxy
L okální zástupce vzdáleného objektu Middleware: Java RMI, CORBA, XML/SOAP,...
Protection proxy
K ontrola či omezování přístupů ke skutečnému objektu
Synchronization proxy
S ynchronizace vláken před voláním metod objektu
Smart pointers/reference
N áhrada běžných ukazatelů (např. v C++) či referencí P očítání referencí a automatické odalokování N ačítání do paměti při první dereferenci
„protection proxy“
Proxy – implementace
Abstraktní proxy pro subjekty více typů Pracuje li se skutečným objektem jen pomocí rozhraní, může být typově nezávislá Konkrétní instanci lze přiřadit např. v konstruktoru:
Graphic * g = new GraphicProtectionProxy(new Image);
Přetížení „->“ v C++ jako proxy Stejná obsluha všech požadavků Virtual proxy – ImagePtr , Real Subject – Image Implementace: Použití:
Image* ImagePtr::LoadImage () { if (image_ == 0) image_ = LoadFile(_imageFile); return image_; } ImagePtr image = ImagePtr("ImgFileName"); image->Draw(Point(0, 0)); // (image.operator->())->Draw(Point(0, 0)) Image* ImagePtr::operator-> () { return LoadImage(); } Image& ImagePtr::operator* () { return *LoadImage(); }
Protection proxy - Java
Řešení problému absence
const
v Javě: Omezená rozhraní
Protection proxies
(wrappers)
public interface java.util.Collection
} public class UnmodifiableCollection
} public static Collection
// nyní se vytvoří neměnná kolekce Collection c = Collections.unmodifiableCollection(lst);
Synchronization proxy - Java
Standardní kolekce nejsou v Javě thread-safe Umožňuje vyšší rychlost Volitelné řešení:
synchronization proxies
(wrappers) Myšlenkově identické s předchozí unmodifiableCollection
public class SynchronizedCollection
} public static Collection
Známé využití - Java RMI (Remote Method Invocation)
public interface HelloIntf extends Remote { public String sayHello() throws RemoteException; } public class Hello extends UnicastRemoteObject implements HelloIntf { public Hello() throws RemoteException { } public String sayHello() throws RemoteException { return "Hello World!"; } } public class Server { public static void main(String[] args) { try { Naming.rebind("Hello", new Hello()); } catch (Exception e) { } } } public class Client { public static void main(String[] args) { try { HelloIntf hello =(HelloIntf)Naming.lookup("/localhost/Hello"); System.out.println(hello.sayHello()); } catch (Exception e) { } } }
Proxy +/-
Vý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 Tvorba sady proxy pro větší subsystém může být zdlouhavá Řešení: automatizace pomocí např. Reflection – opět citelné zpomalení Lepší řešení: vytvoření
Fasády
pro subsystém a jediné proxy (možno sloučit) Klient o proxy vrstvě jakoby neví – nezná možné vedlejší účinky (připojování k síti, náročné operace)
Proxy - související NV
Adapter
Také tvoří mezivrstvu Adaptuje jedno rozhraní na druhé odlišné Proxy implementuje identické rozhraní jako skutečný objekt
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 či může být např. na jiném počítači