130 likes | 436 Views
Proxy. Proxy. Definice zástupce nebo náhradník za dotyčný objekt proxy i zastoupen ý objekt dědí od stejného interfacu proxy kontroluje přístup k objektu. Struktura. ÚČASTNÍCI Subject společné rozhraní RealSubject skutečný objekt Proxy stejné rozhraní jako real subject
E N D
Proxy • Definice • zástupce nebo náhradník za dotyčný objekt • proxy izastoupenýobjektdědí od stejného interfacu • proxy kontroluje přístup k objektu
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 • Kdy se hodí ? • Když je potřeba u klienta ošetřit práci se stavem cílového objektu (synchronizace, bezpečnost, objekt není vytvořen ..) • Situaciošetříme v proxy, klient pracuje s objektem aniž by věděl o jeho stavu⇒zjednodušení kódu • Příklad • Prohlížeč obrázků • seznam všech obrázků ve složce a jejich zobrazení • špatné chování získá seznam obrázků a všechny fotky nahraje do paměti • řešení – zobrazení fotky na vyžádání • elegantní realizace řešení – PROXY
Prohlížeč obrázků class Image { public: virtual ~Image() { }; virtual void showImage() = 0; virtual Size getSize() = 0; }; Subject Proxy RealObject class ImageProxy : public Image { public: ImageProxy(const std::string &fileName); ~ImageProxy() override { }; void showImage() override; Size getSize() override; private: std::string fileName_; Image* proxifiedImage_; }; class RealImage : public Image { public: RealImage( const std::string &fileName); ~RealImage() override { } void showImage() override; Size getSize() override; private: std::string fileName_; void loadImage(); Mat data_; };
Prohlížeč obrázků - implementace RealImage::RealImage( const std::string &fileName) : fileName_( fileName ) { // nacitani fotky z disku do pameti // vypocetne narocne pomale loadImage(); } void RealImage::showImage() { // skutecne renderovani obrazku } ImageProxy::ImageProxy( const std::string &fileName ) : fileName_(fileName) { } void ImageProxy::showImage() { // objekt je vytvořen až ve chvíli kdy je potřeba if ( proxifiedImage_ == nullptr ) { proxifiedImage_ = new RealImage(fileName_ ); } proxifiedImage_->showImage(); } Size RealIMage::getSize() { //vratiinformaci z nactenychdat return Size( data_.rows, data_.cols ) } Size ImageProxy::getSize() { // nactesisirku a vysku z headeruobrazku // mistonacitanicelehoobrazku returnloadSizeFromHeader( fileName_ ); } Image* imProxy1 = new ImageProxy( "img1.jpg" ); Image* imProxy2 = new ImageProxy( "img2.jpg" ); Image* imProxy3 = new ImageProxy( “img3.jpg" ); cout << imProxy3.getSize() << endl; imProxy1->showImage();
Proxy - zoologie Virtual proxy vytváření objektů až v případě potřeby („load on demand“) transparentní provádění optimalizací (Cache proxy, Copy-on-write proxy) Remote proxy lokální zástupce vzdáleného objektu middleware: Java RMI, CORBA, XML/SOAP,... Protection proxy kontrola či omezování přístupů ke skutečnému objektu Smart proxy dodatečné operace při přístupu k objektu Synchronization proxy synchronizace vláken před voláním metod objektu Smart pointers/reference náhrada běžných ukazatelů (zejm. v C++) či referencí počítání referencí a automatické odalokování načí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: Přetížení „->“ v C++ jako proxy stejná obsluha všech požadavků Virtual proxy – ImagePtr, Real Subject – Image Graphic * g = new GraphicProtectionProxy(new Image); Implementace: Image* ImagePtr::LoadImage () { if (image_ == 0) image_ = LoadFile(_imageFile); return image_; } Image* ImagePtr::operator-> () { return LoadImage(); } Image& ImagePtr::operator* () { return *LoadImage(); } Použití: ImagePtr image = ImagePtr("ImgFileName"); image->Draw(Point(0, 0)); // (image.operator->())->Draw(Point(0, 0))
Protection proxy - Java Řešení problému absence const v Javě: omezená rozhraní protection proxies (wrappers) public interface java.util.Collection<E> { boolean contains(Object o); boolean add(E o); //.... } public class UnmodifiableCollection<E> implements Collection<E> { private Collection<? extends E> c; public UnmodifiableCollection(Collection<? extends E> c) { this.c = c; } public boolean contains(Object o) { return c.contains(o); } public boolean add(E o) { throw new UnsupportedOperationException(); } //... } public static Collection<E> unmodifiableCollection(Collection<E> c) { return new UnmodifiableCollection<E>(c); } // vytvoření seznamu List lst = new ArrayList(); // příprava dat apod. // nyní se vytvoří neměnná kolekce Collection c = Collections.unmodifiableCollection(lst);
Synchronization proxy - Java Standardní kolekce nejsou v Javě thread-safe umožňuje to vyšší rychlost Volitelné řešení: synchronization proxies (wrappers) myšlenkově identické s předchozí unmodifiableCollection public class SynchronizedCollection<E> implements Collection<E> { private Collection<? extends E > c; public SynchronizedCollection(Collection<E> c) { this.c = c; } public boolean contains(Object o) { synchronized(this) {return c.contains(o);} } public boolean add(E o) { synchronized(this) {return c.add(o);} } //... } public static Collection<E> synchronizedCollection(Collection<E> c) { return new SynchronizedCollection<E>(c); } // typický příklad - nepotřebujeme nesynchronizovanou instanci List l = Collections.synchronizedList(new LinkedList());
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í NV • Nevýhody • snižení efektivity kvuli vrstvě indirekce navíc • tvorba sady proxy pro větší subsystém může být zdlouhavá • řešení: automatizace pomocí např. Reflection • lepší řešení: vytvoření Fasády pro subsystém a jediné proxy (možno sloučit) • může generovat vlastní výjimky (remote proxy) • nebezpečí overkillu přes sofistikované strategie (cache proxy)
Proxy - související NV • Adapter • též tvoří mezivrstvu • adaptuje jedno rozhraní na druhé odlišné • proxy implementuje identické rozhraní jako skutečný objekt • Decorator • podporuje dynamické i rekurzivní přiřazení skutečného objektu • 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 • Factory • sem lze zabalit rozhodnutí, jestli vyrobím skutečný objekt nebo proxy