Úvod - problém. Při přidání nového modelu je nutné upravit. Kód, který se nebu de často měnit. n Mějme obchod s auty:

Podobné dokumenty
Kód, který se nebude často měnit

Abstract Factory úvod

specifikuje vytvářené objekty pomocí prototypické instance nový objekt vytváří kopírováním prototypu

Návrhové vzory. n OO jazyky - široká paleta technických prostředků. n Návrhový vzor. n rozhraní!! n volnější vazby, parametrizace

Literatura. E. Gamma, R. Helm, R. Johnson, J. Vlissides The Gang of Four (GoF) Design Patterns Elements of Reusable Object-Oriented Software 1995

Bridge. Známý jako. Účel. Použitelnost. Handle/Body

Semin aˇr Java N avrhov e vzory Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Duben 2009 Radek Koˇc ı Semin aˇr Java N avrhov e vzory 1/ 25

Semin aˇr Java N avrhov e vzory Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Duben 2008 Radek Koˇc ı Semin aˇr Java N avrhov e vzory 1/ 24

Návrhové vzory. Jakub Klemsa, Jan Legerský. 30. října Objektově orientované programování.

Základy objektové orientace I. Únor 2010

Třídy a objekty. Třídy a objekty. Vytvoření instance třídy. Přístup k atributům a metodám objektu. $z = new Zlomek(3, 5);

Návrhové vzory OMO, LS 2014/2015

Využití OOP v praxi -- Knihovna PHP -- Interval.cz

24. listopadu 2013, Brno Připravil: David Procházka

OMO. 4 - Creational design patterns A. Singleton Simple Factory Factory Method Abstract Factory Prototype Builder IoC

Dědičnost (inheritance)

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

1. Dědičnost a polymorfismus

20. Projekt Domácí mediotéka

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

Objekty v PHP 5.x. This is an object-oriented system. If we change anything, the users object.

Generické programování

Úvod do programovacích jazyků (Java)

Objektově orientované programování v PHP 5. Martin Klíma

návrhový vzor Singleton.

Class loader. každá třída (java.lang.class) obsahuje referenci na svůj class loader. Implementace class loaderu

Java a XML. 10/26/09 1/7 Java a XML

UJO Framework. revoluční architektura beans. verze

State. Známý jako. Účel. Použitelnost. Stav, Object for States. umožňuje objektu měnit svoje chování v závislosti na stavu objekt mění svou třídu

typová konverze typová inference

Seminář Java IV p.1/38

PB161 Programování v jazyce C++ Přednáška 7

PB161 Programování v jazyce C++ Přednáška 7

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

Třídy. Instance. Pokud tento program spustíme, vypíše následující. car1 má barvu Red. car2 má barvu Red. car1 má barvu Blue.

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Třídy, polymorfismus. A0B36PR2-Programování 2 Fakulta elektrotechnická České vysoké učení technické

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

NA CO SI DÁT POZOR V JAVASCRIPTU? Angular.cz

Návrhový vzor Factory v JAVA API

RMI Remote Method Invocation

PREPROCESOR POKRAČOVÁNÍ

Semin aˇr Java X Radek Koˇc ı Fakulta informaˇcn ıch technologi ı VUT Duben 2011 Radek Koˇc ı Semin aˇr Java N avrhov e vzory, Z asady...

Motivační příklad reálný svět. výroba (assembly line)

Čipové karty Lekařská informatika

Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost rozhraním a výjimkám.

KTE / ZPE Informační technologie

Dynamicky vázané metody. Pozdní vazba, virtuální metody

4. ZÁKLADNÍ POJMY Z OBJEKTOVĚ ORIENTOVANÉHO PROGRAMOVÁNÍ

Obsah Znovupou ˇzitelnost N avrhov e vzory Z asady programov an ı Radek Koˇc ı Semin aˇr Java N avrhov e vzory, Z asady... 2/ 46

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

Objektové programování

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Reflexe. Aplikační programování v Javě (BI-APJ) - 8 Ing. Jiří Daněček Katedra softwarového inženýrství Fakulta informačních technologií ČVUT Praha

Programování v C++ 1, 6. cvičení

Programování v C++ 2, 7. cvičení

Jazyk C# (seminář 3)

Dědičnost. seskupování tříd do hierarchie. potomek získá všechny vlastnosti a metody. provádí se pomocí dvojtečky za názvem třídy.

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

Java a Caché IV: Manipulace s objekty

Webové služby a XML. Obsah přednášky. Co jsou to webové služby. Co jsou to webové služby. Webové služby a XML

ČÁST 1. Zahřívací kolo. Co je a k čemu je návrhový vzor 33

11 Diagram tříd, asociace, dědičnost, abstraktní třídy

Abstraktní třída a rozhraní

SOUBORY, VSTUPY A VÝSTUPY POKRAČOVÁNÍ

Vzor Továrna - Factory

1. Programování proti rozhraní

IB111 Programování a algoritmizace. Objektově orientované programování (OOP)

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Teoretické minimum z PJV

Dědění, polymorfismus

Chain of responsibility

Java - výjimky. private void vstup() throws IOException {... }

Programování v C++ 3, 3. cvičení

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Z. Kotala, P. Toman: Java ( Obsah )

PB161 Základy OOP. Tomáš Brukner

10 Generické implementace

NMIN201 Objektově orientované programování 1 / :36:09

NPRG031 Programování II 1 / :25:46

Polymorfismus. Porovnání jazyků z hlediska polymorfismu Jazyky C, C++, C# Jazyk Java PHP a jiné Na závěr souhrn vlastností jednotlivých jazyků

Distribuované systémy a výpočty

Algoritmizace a programování

Java Výjimky Java, zimní semestr

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

Programování II. Abstraktní třída Vícenásobná dědičnost 2018/19

11. Dědičnost. Dědičnost strana 103

Obsah přednášky 9. Skrývání informací. Skrývání informací. Zapouzdření. Skrývání informací. Základy programování (IZAPR, IZKPR) Přednáška 9

Struktura třídy, operátory, jednoduché algoritmy, junit. Programování II 2. cvičení Alena Buchalcevová

Programování II. Polymorfismus

<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

Principy objektově orientovaného programování

Design Patterns. Tomáš Herceg Microsoft MVP (ASP.NET)

3. Třídy. Základní pojmy objektového programování. Třídy

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Vláknové programování část V

Enterprise Java Beans 3.0

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

Výjimky. Tomáš Pitner, upravil Marek Šabo

Transkript:

Factory Method

Úvod - problém n Mějme obchod s auty: public class OrderCars { public Car ordercar(string model) { Car car; Při přidání nového modelu je nutné upravit if(model.equals("mark IV")) { car = new Mercury(model); else if(model.equals("corvette")) { car = new Chevrolet(model); else if(model.equals("fusion")) car = new Ford(model); else if(model.equals("enzo")) { car = new Ferrari(model); else if(model.equals("fabia")) { car = new Skoda(model); car.buildcar(); car.testcar(); car.shipcar(); Kód, který se nebu de často měnit n Problém míchání relativně stálého kódu s kódem, který se bude měnit při každém přidání nové třídy n Problém míchání úrovní abstrakce auto X Fabia

Řešení předchozího problému public abstract class CarFactory { abstract Car createcar(string model); Vytvoření objektu využívá polymorfismu public Car ordercar(string model) { Car car = createcar(model); car.buildcar(); car.testcar(); car.shipcar(); return car; Business logika public class FordFactory extends CarFactory { Car createcar(string model) { if(model.equals("fusion")) { return new Ford(model); else if(model.equals("mark IV")) return new Mercury(model); else { return null; n Vytvoření frameworku pro objednávání aut n Při přidání nového auta => pouze změna FordFactory.createCar

n Známý jako Factory Method q Tovární metoda q public Constructor n Účel q Definuje rozhraní pro vytvoření objektu q Potomci sami rozhodují kterou třídu instanciovat q Umožňuje odložit instanciaci z předka na potomka n Kategorie q Class Creational (Tvořivé návrhové vzory) n Využití q Vytváření frameworků n Třída nezná objekty, které má vytvářet n Potomci specifikují vytvářené objekty q záleží na programátoři, kolik konkrétních potomků vytvoří q Oddělení kódu, který se mění často, od neměnného

n Struktura Factory Method - struktura n Účastníci q Product (Car) n definuje rozhraní objektů vytvářených tovární metodou q ConcreteProduct (Fabia) n implementuje rozhraní Productu q Creator (CarFactory) n deklaruje tovární metodu vracející objekt typu Product n může definovat defaultní implementaci vracející defaultní objekt ConcreteProduct q ConcreteCreator (FordFactory) n implementuje tovární metodu vracející instanci ConcreteProductu

Factory Method - paralelní hierarchie n Propojení paralelních hierarchií tříd q třída deleguje některé akce na jinou třídu q příklad: manipulovatelné grafické objekty (úsečka, obdélník, kruh,...) n stav manipulace je nutné udržovat pouze během manipulace - ne u grafického objektu n manipulace různých objektů uchovávají jiný stav (koncový bod, rozteč řádků,...) n objekt Manipulator, konkrétní grafické objekty mají vlastní manipulátory n paralelní hierarchie n Figure deklaruje CreateManipulator, potomci vytvářejí vlastní manipulátory n částečně paralelní hierarchie - dědění defaultního manipulátoru

Factory Method - implementace n Implementace q dvě hlavní varianty n Creator je abstraktní třída, nemá vlastní implementaci tovární metody q nutnost dědičnosti a vlastní implementace n Creator je konkrétní třída s defaultní implementací q flexibilita q pravidlo: Vytvářet objekty v separátní metodě => potomci mohou ovlivnit (polymorfismus), které třídy se budou instanciovat. q parametrizované tovární metody n variace - více druhů produktů n tovární metoda dostane parametr identifikující druh objektu (ProdId) n všechny objekty sdílejí rozhraní Productu class Creator { Product create (ProdId id) { if(id==mine) return new MyProd; if(id==yours) return new YourProd; return 0; class MyCreator extend Creator { Prod create (ProdId id) { if(id==mine) return new MyProd2; if(id==theirs) return new TheirProd; return super.create(id); Obsluha ostatních id se deleguje na předka

Factory Method - implementace q pozdní inicializace n tovární metody jsou vždy virtuální, často čistě virtuální - pozor na volání z konstruktorů n lazy initialization - přístup pouze přes přístupovou metodu (accessor) n konstruktor Creatoru inicializuje ukazatel na 0 n v případě potřeby se produkt vytvoří 'na žádost' class Creator { private Product product; public final Product getproduct() { if (product == null) { product = createproduct(); return product; accessor protected Product createproduct(); inicializace na žádost

Factory Method - implementace q použití šablon C++ n někdy zbytečně pracné vytvářet konkrétní potomky n šablona parametrizovaná Produktem n není zapotřebí vytvářet potomky Creatora class Creator { public: public Product* CreateProduct() = 0; ; template <class T> class StdCreator: public Creator { public: public Product* CreateProduct(); ; template <class T> Product* StdCreator<T>::CreateProduct() { return new T; vrací konkrétního potomka abstraktního produktu class MyProduct : public Product { public: MyProduct(); //... ; StdCreator<MyProduct> mycreator;

Factory Method - implementace q použití šablon Java n někdy zbytečně pracné vytvářet konkrétní potomky n šablona parametrizovaná Produktem n není zapotřebí vytvářet potomky Creatora n reflexe nejsou tak hezké class Creator { public Product createproduct() { ; class StdCreator<T extends Product> extends Creator { private Class<T> clazz; public StdCreator(Clazz<T> clazz) { this.clazz = clazz public Product createproduct() { try{ return clazz.newinstance() catch (Exception) { // do not ever do this!!!! // Unless u are a pervert! ; class MyProduct extends Product {. ; StdCreator<MyProduct> mycreator;

Factory Method - bludiště n CreateMaze má napevno použité třídy pro komponenty n Factory Method umožní potomkům volbu komponent class MazeGame { public Maze createmaze(); // factory methods: public Maze makemaze(){ return new Maze90; public Room makeroom(int n) { return new Room(n); public Wall makewall() { return new Wall90; public Door makedoor(room* r1, Room* r2) { return new Door(r1, r2); ; n Tovární metody vrací příslušnou komponentu n MazeGame obsahuje defaultní implementace

Factory Method - bludiště class MazeGame { Maze createmaze () { Maze amaze = makemaze(); Room r1 = makeroom(1); Room r2 = makeroom(2); Door thedoor = makedoor(r1, r2); amaze.addroom(r1); amaze.addroom(r2); r1.setside(north, makewall()); r1.setside(east, thedoor); r1.setside(south, makewall()); r1.setside(west, makewall()); r2.ssetside... return amaze; class BombedMazeGame extends MazeGame { public BombedMazeGame(); public Wall makewall() const { return new BombedWall; public Room makeroom(int n) const { return new RoomWithABomb(n); ; potomci implementují specializace různých komponent class EnchantedMazeGame extends MazeGame { public EnchantedMazeGame(); public Room* MakeRoom(int n) { return new EnchantedRoom(n, castspell()); public Door* MakeDoor(Room r1, Room r2) { return new DoorNeedingSpell(r1, r2); protected Spell castspell() {; ;

Factory Method - bludiště class MazeGame { Maze createmaze () { Maze amaze = makemaze(); Room r1 = makeroom(1); Room r2 = makeroom(2); Door thedoor = makedoor(r1, r2); amaze.addroom(r1); amaze.addroom(r2); r1.setside(north, makewall()); r1.setside(east, thedoor); r1.setside(south, makewall()); r1.setside(west, makewall()); r2.ssetside... return amaze; class BombedMazeGame extends MazeGame { public BombedMazeGame(); public Wall makewall() const { return new BombedWall; public Room makeroom(int n) const { return new RoomWithABomb(n); ; potomci implementují specializace různých komponent class EnchantedMazeGame extends MazeGame { public EnchantedMazeGame(); public Room makeroom(int n) { return new EnchantedRoom(n, castspell()); public Door makedoor(room r1, Room r2) { return new DoorNeedingSpell(r1, r2); protected Spell castspell() {; ;

Factory Method příklady použití n Qt gui framework (C++) public Qmenu* QmainWindow::createPopupMenu() n Java API XML parsery, DateFormat třída q DocumentBuilderFactory, DocumentBuilder q SAXParserFactory, SAXParser Factory method DateFormat df1 = DateFormat.getDateInstance(DateFormat.FULL, Locale.FRANCE); n Zend webový aplikační framework (PHP) q Třída Zend_Db connector k různým typům databází // require_once 'Zend/Db/Adapter/Pdo/Mysql.php'; // Automatically load class Zend_Db_Adapter_Pdo_Mysql // and create an instance of it. $db = Zend_Db::factory('Pdo_Mysql', array( 'host' => '127.0.0.1', 'username' => 'webuser', 'password' => 'xxxxxxxx', 'dbname' => 'test' )); Factory method Pdo_Sqlite, Pdo_Mssql, Oracle, DB2,...

Factory Method příklady použití public static function factory($adapter, $config = array()) { // obtaining adapter class name $adaptername = strtolower($adapternamespace. '_'. $adapter); // Load the adapter class. This throws an exception // if the specified class cannot be loaded. @Zend_Loader::loadClass($adapterName); Factory method // Create an instance of the adapter class. // Pass the config to the adapter class constructor. $dbadapter = new $adaptername($config); Concrete Product // Verify that the object created is // a descendent of the abstract adapter type. if (! $dbadapter instanceof Zend_Db_Adapter_Abstract) { // throwing Zend_Db_Exception require_once 'Zend/Db/Exception.php'; test of Product base class throw new Zend_Db_Exception("Adapter class '$adaptername' does not extend Zend_Db_Adapter_Abstract"); return $dbadapter;

n Shrnutí Factory Method - související návrhové vzory q flexibilita za relativně malou cenu q obvyklá základní metoda zvýšení flexibility n public constructor q časté využití jinými vzory n Abstract Factory q často implementovaná pomocí továrních metod n Template Method q často volány tovární metody n Prototype q nevyžaduje dědění Creatora q... avšak vyžaduje navíc inicializaci produktové třídy