Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Abstract Factory. Abstract Factory – úvod Situace  potřebujeme vytvářet objekty ze skupiny souvisejících nebo na sobě závislých tříd  2 „druhy“ GUI.

Podobné prezentace


Prezentace na téma: "Abstract Factory. Abstract Factory – úvod Situace  potřebujeme vytvářet objekty ze skupiny souvisejících nebo na sobě závislých tříd  2 „druhy“ GUI."— Transkript prezentace:

1 Abstract Factory

2 Abstract Factory – úvod Situace  potřebujeme vytvářet objekty ze skupiny souvisejících nebo na sobě závislých tříd  2 „druhy“ GUI – Windows a OSX  skupiny obsahují stejnou sadu objektů  Windows i OSX obsahují nějaký objekt pro tlačítko, okno, scrollbar, …  jednotlivé objekty se chovají logicky stejně  na WinButton i OSXButton lze kliknout,... Chtěli bychom:  snadno vyměňovat a přidávat jednotlivé skupiny tříd  neduplikovat zbytečně kód pro objekty, které se chovají takřka stejně  odstínit uživatele od samotného vytváření objektů a jejich implementace  zajistit koherenci vytvářených objektů

3 Abstract Factory – idea práce Co s tím?  objekty budeme vytvářet pomocí továren ( WinGUIFactory, OSXGUIFactory, …)  uživatel nevolá new ale createSomeObject()  definujeme abstraktní továrnu – předek všech konkrétních továren  definujeme rozhraní pro vytvářené objekty  obecný typ Button, TextBox, ScrollBar, … Použití  zveřejníme pouze rozhraní továren a vytvářených objektů  na počátku si uživatel zvolí, kterou továrnu chce používat  a dále již pracuje pouze s rozhraními  podobně jako v případě knihoven funkcí

4 Abstract Factory – příklad Abstraktní produkty – rozhraní pro jednotlivé widgety Konkrétní produkty – implementace vzhledu pro „ScrollBar“ Abstraktní továrna – určuje rozhraní konkrétních továren Konkrétní továrny – implementují rozhraní abstraktní továrny Uživatel – pracuje pouze s rozhraními (tj. WidgetFactory, Window, ScrollBar)

5 Abstract Factory – příklad Abstraktní produkty – rozhraní pro jednotlivé widgety Konkrétní produkty – implementace vzhledu pro „TextBox“ Abstraktní továrna – určuje rozhraní konkrétních továren Konkrétní továrny – implementují rozhraní abstraktní továrny Uživatel pracuje pouze s rozhraními (tj. WidgetFactory, Button, TextBox) Konkrétní produkty – implementace vzhledu pro „Button“ Konkrétní továrny – implementují rozhraní abstraktní továrny

6 Abstract Factory – shrnutí účastníků Abstraktní produkty ( Button, TextBox )  rozhraní objektů vytvářených v továrně Abstraktní továrna ( GUIFactory )  rozhraní pro vytváření objektů  vrací „abstraktní“ objekty Aplikace/uživatel ( Application )  Pracuje pouze s abstraktními objekty, konkrétní jsou mu skryty Konkrétní produkty ( WinButton, WinTextBox, OSXButton, OSXTextBox )  skutečné objekty  implementují rozhraní jednotlivých abstraktních produktů Konkrétní továrny ( OSXGUIFactory, WinGUIFactory )  implementují rozhraní abstraktní továrny  vytváří skutečné (konkrétní) objekty

7 Abstract Factory – výhody a problémy Výhody  snadná změna skupiny tříd  stačí použít jinou konkrétní továrnu  zaručuje použití komponent z (pouze) jedné skupiny  WinButton + WinTextBox, OSXButton + OSXTextBox  vynucuje použití abstraktních rozhraní ( Button, TextBox )  jeden uživatelský kód pro všechny továrny Potenciální problémy  omezení funkčnosti  konkrétní produkty mohou podporovat pouze „průnik“ množin funkcí „základních“ objektů  přidávání nových skupin  pro každou novou skupinu je nutné implementovat všechny metody  řešení: abstraktní továrna nemusí být abstraktní  přidávání druhů objektů  nutná změna rozhraní a všech konkrétních továren  řešení: rozšiřitelná továrna

8 Abstract Factory – rozšiřitelná implementace Vlastnosti  pouze jedna metoda – parametr určuje produkt, který má být vytvořen  eliminuje nutnost změny rozhraní všech továren při přidání nového produktu  všechny produkty musí mít společného předka ( Widget )  ztrácíme typovou kontrolu!  používáno především v dynamicky typovaných jazycích, ve staticky typovaných se musí provádět přetypování na abstraktní produkt (obecné tlačítko, …) class GUIFactory { public: virtual Widget* Create(WidgetId id); }; Widget* GUIFactory::Create(WidgetId id) { switch (id) { /* generic widgets */ case BUTTON: return new Button(); case LABEL: return new Label(); default: return 0; } class OSXFactory: public GUIFactory { public: virtual Widget* Create(WidgetId id); }; Widget* OSXFactory::Create(WidgetId id) { switch (id) { case BUTTON: /* “override” */ return new OSXButton(); case TextBox: /* nový typ */ return new OSXTextBox(); default: /* “fallback” */ return GUIFactory::Create(id); }

9 Abstract Factory – dynamická implementace Vlastnosti  továrna spravuje mapování: identifikátor typu  vytvořující funkce  konkrétní typy vytvářených objektů se registrují jednotlivě za běhu  stačí jedna univerzální implementace továrny  použití – systémy, kde neznáme přesné typy při kompilaci class Factory { typedef AbstractProduct* (*ProductCreator)(); map mapping; public: bool Register(IdType id, ProductCreator creator) { return mapping.insert(make_pair(id, creator)).second; } bool Unregister(IdType id) { return mapping.erase(id) == 1; } AbstractProduct* CreateObject(IdType id) { auto it = mapping.find(id); if (it != mapping.end()) return (*it->second)(); return 0; } };

10 Abstract Factory – implementace pomocí prototypů Pouze jedna továrna obsahující prototypy  pro změnu typů vytvářených objektů stačí změnit prototypy v továrně  objekty vytvářeny klonováním prototypů speciální virtuální metodou  pomocí prototypů lze implementovat všechny tři uvedené typy továren class CloneFactory { Button *buttonPrototype; Window *windowProtototype; public: CloneFactory(Button *buttonProt, Window *windowProt): buttonPrototype(buttonProt), windowPrototype(windowProt) {} ~Factory() { delete buttonPrototype; delete windowProtototype; } Button* CreateButton() { return buttonPrototype->Clone(); } Window* CreateWindow() { return windowPrototype->Clone(); } };

11 Abstract Factory – bludiště Program stavící bludiště dostane MazeFactory jako parametr Příklad konkrétní abstraktní továrny  poskytuje defaultní implementaci class MazeFactory { public: // factory methods: virtual Maze* MakeMaze() const { return new Maze; } virtual Room* MakeRoom(int n) const { return new Room(n); } virtual Wall* MakeWall() const { return new Wall; } virtual Door* MakeDoor(Room* r1, Room* r2) const { return new Door(r1, r2); } };

12 Abstract Factory – bludiště Potomci implementují specializace jednotlivých komponent Továrna zajišťuje konzistenci komponent  RoomWithABomb má kolem sebe BombedWalls class EnchantedMazeFactory: public MazeFactory { public: virtual Room* MakeRoom(int n) const { return new EnchantedRoom(n, CastSpell()); } virtual Door* MakeDoor(Room* r1, Room* r2) const { return new DoorNeedingSpell(r1, r2); } protected: Spell* CastSpell() const; }; class BombedMazeFactory: public MazeFactory { public: virtual Wall* MakeWall() const { return new BombedWall; } virtual Room* MakeRoom(int n) const { return new RoomWithABomb(n); } };

13 Abstract Factory – bludiště Maze* CreateMaze(MazeFactory *f) { Maze* aMaze = f->MakeMaze(); Room* r1 = f->MakeRoom(1); Room* r2 = f->MakeRoom(2); Door* d1 = f->MakeDoor(r1, r2); aMaze->AddRoom(r1); aMaze->AddRoom(r2); r1->SetSide(North, f->MakeWall()); r1->SetSide(East, d1); r1->SetSide(South, f->MakeWall()); r1->SetSide(West, f->MakeWall());... return aMaze; } Maze* MazeGame::CreateMaze() { Maze* aMaze = new Maze; Room* r1 = new Room(1); Room* r2 = new Room(2); Door* d1 = new Door(r1, r2); aMaze->AddRoom(r1); aMaze->AddRoom(r2); r1->SetSide(North, new Wall); r1->SetSide(East, d1); r1->SetSide(South, new Wall); r1->SetSide(West, new Wall);... return aMaze; } Tvorba bludiště s použitím továrny jako parametru. Řešení bez továrny.

14 Abstract Factory – použití v Java AWT AWT  Abstract Window Toolkit  každá AWT komponenta (Component) obsahuje odpovídající objekt daného systému (ComponentPeer) java.awt.Toolkit  AbstractFactory  potomci vrací příslušné objekty daného systému (MS Windows, X Window)  createMenu(), createButton(), …  getDefaultToolkit(), getToolkit() public static Toolkit getDefaultToolkit() { if (toolkit == null) { String nm = System.getProperty( "awt.toolkit", "sun.awt.motif.MToolkit"); toolkit = (Toolkit) Class.forName(nm). newInstance(); } return toolkit; }

15 Abstract Factory – další příklady použití Práce s databázemi  aplikace přistupující k různým databázím (MySQL, Oracle, …)  každá má trochu specifické rozhraní, ale základní operace jsou typicky stejné (connect, SQL dotaz, …)  nemusí se jednat pouze o klasické databáze, ale i jiná úložiště dat – např. XML  uživatel zavolá „factory->createConnection()“, dostane připojení ke správné databázi  továrna může spravovat i informace o umístění databáze, jednoduché rozkládání zátěže v případě více databázových serverů  uživatel si pouze řekne o OracleFactory a více „neřeší“ Přístup k filesystémům  chceme pracovat se soubory na různých filesystémech  interně se jejich implementace zásadně liší  na venek takřka totožné rozhraní (open, write, close, …)  abstraktní továrna zde působí jako poklička – uživatel neví, se kterým FS pracuje

16 Abstract Factory – další příklady použití Komunikace po síti  poklička nad protokoly na zvolené síťové vrstvě (typicky transportní)  může se starat např. i o zajišťování spolehlivosti nad UDP v situacích, kdy není vhodné použít TCP  využití více aplikačních protokolů ke stejnému účelu (http, WebDAV, ssh, nfs) Využití odlišných grafických prvků  multiplatformní uživatelské rozhraní  podpora Windows, Mac OS X i Linux Vývoj Abstract Factory  změny vůči původnímu návrhu v GoF  ovládaní kompletního lifecyklu včetně destrukce  využívání kombinace Builderu a Abstract Factory

17 Abstract Factory – shrnutí Definice abstraktní továrny  rozhraní pro vytváření rodin souvisejících nebo závislých objektů Význam použití  udržení úrovně abstrakce při návrhu API  koherence používaných implementací  správa destrukce objektů Jakou implementaci?  je třeba citlivě volit mezi flexibilitou a typovou kontrolou  ujasnit si, zda je horší sahat do uživatelského kódu nebo do všech konkrétních továren Související vzory  Factory Method – abstraktní továrna často používá tovární metody  Prototype – abstraktní továrna, může být implementována i pomocí prototypů  Builder – vzor používaný k vytváření objektů s podobným procesem inicializace  Singleton – typicky není třeba mít více než jednu továrnu

18 Dotazy? Abstract Factory

19 Zdroje E. Gamma, R. Helm, R. Johnson, J. Vlissides: Design Patterns - Elements of Reusable Object-Oriented Software (upraveno)


Stáhnout ppt "Abstract Factory. Abstract Factory – úvod Situace  potřebujeme vytvářet objekty ze skupiny souvisejících nebo na sobě závislých tříd  2 „druhy“ GUI."

Podobné prezentace


Reklamy Google