Bridge Pavel Kalvoda Motivace Motivace Exploze počtu tříd Klient musí znát implementaci Exploze počtu tříd.
Download
Report
Transcript Bridge Pavel Kalvoda Motivace Motivace Exploze počtu tříd Klient musí znát implementaci Exploze počtu tříd.
Bridge
Pavel Kalvoda
Motivace
Motivace
Exploze počtu tříd
Klient musí znát
implementaci
Exploze počtu tříd
Hierarchie typů se těžko
mapuje na implementaci
Klient musí znát
implementaci
Exploze počtu tříd
Řešení
Rozdělme hierarchii rozhraní a jejich
implementací
Řešení
Rozdělme hierarchii rozhraní a jejich implementací
Řešení
Rozdělme hierarchii rozhraní a jejich implementací
Klientská část rozhraní
Řešení
Rozdělme hierarchii rozhraní a jejich implementací
Abstrakce
implementace
Klientská část rozhraní
Řešení
Rozdělme hierarchii rozhraní a jejich implementací
Abstrakce
implementace
Klientská část rozhraní
Implementováno
pomocí abstraktní
implementace
Řešení
Omezuje šířku rozhraní
Řešení
Omezuje šířku rozhraní
Specifičtější rozhraní jsou
implementována pomocí
stávajících metod
Řešení
Omezuje šířku rozhraní
Rozšiřitelné bez
ohledu na
implementaci
WindowImp
Specifičtější rozhraní jsou
implementována pomocí
stávajících metod
Řešení
Omezuje šířku rozhraní
Decouplované od
klientského rozhraní
Rozšiřitelné bez
ohledu na
implementaci
WindowImp
Specifičtější rozhraní jsou
implementována pomocí
stávajících metod
Bridge – struktura
Struktura
Účastníci
rozšiřuje rozhraní definované v Abstraction
Implementor
definuje abstraktní rozhraní objektů, obsahuje odkaz na implementaci
metody realizovány pomocí metod rozhraní Implementor
RefinedAbstraction
typicky obsahuje jen
primitivní operace
Abstraction
definuje složitější operace
pomocí jednodušších z
Implementoru
představuje rozhraní implementací, rozhraní se může lišit od Abstraction
ConcreteImplementor
konkrétní implementace rozhraní Implementor
Bridge
Účel
odděluje rozhraní od konkrétní implementace
předchází nárůstu počtu tříd při přidávání implementací
umožňuje nezávislý vývoj implementace
umožňuje snadnou kompozici a “horizontální znovupoužitelnost” implementací
Další jména
handle & body
Cheshire cat
PIMPL (Pointer to IMPLementation)
Předpoklady
danou abstrakci navrhujeme
existuje vhodný rozklad do primitivních operací
Bridge – použití
Kdy je vhodné použít návrhový vzor Bridge?
Nechceme, aby rozhraní a implementace byly pevně svázány
Chceme mít abstrakce a jejich implementace rozšiřitelné pomoci dědičnosti
privátní data a metody se píší do hlavičkového souboru (C++)
Chceme sdílet implementaci mezi více objekty
není nutná rekompilace (stačí znovu pustit linker)
Chceme skrýt detaily implementace
kombinovat a nezávisle rozšiřovat
Chceme, aby změny v implementaci neměly vliv na klientský kód
možnost výběru nebo přepínání implementace za běhu
nechceme, aby o tom klient věděl
např. reference counting, structural sharing immutable objektů
Mnoho dimenzí aspektů?
např. platforma, funkcionalita, přesnost výpočtu, atd.
ApproximateLinuxCertifyingRemoteX
Bridge – příklad
Příklad: multiplatformní systém pro tvorbu GUI
rozhraní objektů
class Window {
private: WindowImp imp;
odkaz na Implementora
rozhraní
pro potomky
public:
void DrawContents() = 0;
void DrawRect( Point p1, Point p2) {
WindowImp imp = getWindowImp();
imp.Rect( p1.getX(), p1.getY(), p2.getX(), p2.getY());
implementace
pomocí
delegace
}
protected WindowImp getWindowImp() {
if (imp == null) {
imp = WindowFactory.getInstance.makeWindowImp();
}
return imp;
}
inicializace
na žádost
}
rozšířené rozhraní
class IconWindow : public Window {
public: void DrawContents() {
WindowImp imp = getWindowImp();
imp.Bitmap(”icon”, new Coord(0.0), new Coord(0.0));
}
}
konkrétní
implementace
delegace
Bridge – příklad
Příklad: multiplatformní systém pro tvorbu GUI
rozhraní implementací
poskytuje primitivní metody pro vykreslování
class WindowImp {
void Rect(Coord c1, Coord c2, Coord c3, Coord c4) = 0;
void Text(String string, Coord c1, Coord c2) = 0;
void Bitmap(String string, Coord c1, Coord c2) = 0;
...
}
implementace
XWindow a WinWindow implementují rozhraní WindowImp
poskytují konkrétní kreslící funkce
mohou obsahovat privátní atributy určující stav okna
class XWindowImp : WindowImp {
public: void DeviceRect( Coord c1, Coord c2, Coord c3, Coord c4) { ... }
...
}
class WubWindowImp implements WindowImp {
public: void DeviceRect( Coord c1, Coord c2, Coord c3, Coord c4) { ... }
...
}
Bridge – ve volné přírodě
Java GUI toolkit je učebnicový příklad
třídy java.awt.*
jsou realizovány platform-specific implementacemi v
java.awt.peer.*Peer
Bridge – varianty, diskuze
Jeden Implementor
degenerovaný případ
stačí jeden konkrétní Implementor, nepotřebujeme abstraktního předka
účel: skrytí detailů implementace
Abstraction obsahuje pouze referenci na objekt třídy Implementor
při změně implementace není třeba rekompilovat klientský kód
Více Implementorů
Implementor se vybere v konstruktoru Abstraction
konstruktor lze parametrizovat – RT výběr implementace
Implementor se vybere za běhu, lze ho za běhu změnit
implementaci může vytvářet i Abstract Factory
Sdílení Implementorů
Implementor je sdílen více objekty
více objektů Abstraction referencuje stejný objekt Implementor
C++ - reference counting
pro zrušení implementace po zrušení posledního odkazu
Bridge – podněty k zamyšlení
Chci aby Refined abstraction využilo specifického implementora
Chci v Refined abstraction použít specifické rozhraní specifického
implementora
Zjistil jsem, že primitvní funkce Implemetora je potřeba změnit
Bridge – související návrhové vzory
Související návrhové vzory
Abstract Factory
Adapter
stejně jako Bridge implementuje rozhraní jedné třídy pomocí metod jiné třídy
používá se v případě, že chceme nějakou již existující třídu přizpůsobit
požadovanému rozhraní
Bridge se používá už v době návrhu tříd
Facade
vytváří instance implementací
java.awt.Toolkit, java.sql.DriverManager
pár Abstrakce a Implementor jsou degerovaný případ
Abstrakce může zjednodušovat rozhraní Implementoru
Spíše nesouvisející návrhové vzory
Proxy
Decorator
Bridge – alternativní pohled
V jazyce s mixiny
Specifika implementací vyčleníme do mixinů
Hierarchie v Abstrakci bude sloužit pro implementaci klientského kontraktu
Pokud to jazyk dovolí, můžeme mixiny využívat dynamicky
https://gist.github.com/PJK/d788875dcb886de92cc2
http://repl.it/d9q/2
Je Bridge náhrada za syntaktické pozlátko mixinů?
Odkazy a zdroje
Diskuze