Stáhnout prezentaci
Prezentace se nahrává, počkejte prosím
ZveřejnilAntonín Beran
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 http://upload.wikimedia.org/wikipedia/commons/a/a7/Abstract_factory.svg (upraveno)
Podobné prezentace
© 2024 SlidePlayer.cz Inc.
All rights reserved.