Gyári módszer (tervezési minta)

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2018. szeptember 11-én felülvizsgált verziótól ; az ellenőrzések 32 szerkesztést igényelnek .
gyári módszer
Gyári módszer

Gyári módszer
Típusú Generálás
Célja Különböző típusú objektumok létrehozása egy felülettel
profik Objektumok létrehozása, függetlenül azok típusától és a létrehozási folyamat összetettségétől.
Mínuszok Még egyetlen objektumhoz is létre kell hozni egy megfelelő gyárat, ami növeli a kódot.
Leírása: Tervezési minták Igen

A gyári metódus ( eng.  Factory Method ) vagy a virtuális konstruktor ( eng.  Virtual Constructor ) egy generáló tervezési minta , amely alosztályokat (gyermekosztályokat, alosztályokat) biztosít interfésszel egy adott osztály példányainak létrehozásához. A létrehozáskor a leszármazottak meghatározhatják, hogy melyik osztályt hozzanak létre. Más szóval, ez a sablon az objektumok létrehozását a szülő osztály leszármazottaira ruházza . Ez lehetővé teszi, hogy a programkódban ne konkrét osztályokat használjunk, hanem az absztrakt objektumokat magasabb szinten kezeljük.

Cél

Interfészt határoz meg egy objektum létrehozásához, de az alosztályokra bízza, hogy eldöntsék, melyik osztályra alapozzák az objektumot. A gyári metódus lehetővé teszi egy osztály számára, hogy delegálja az alosztályok létrehozását. Amikor:

Szerkezet

Előnyök

Hátrányok

Kódpéldák

Swift

Gyors példa Protocol Product {     func getName () -> String } class ConcreteProductA : Termék {     func getName () -> String {  return "ConcreteProductA" } } class ConcreteProductB : Product {     func getName () -> String { return "ConcreteProductB" } } Protocol Creator {     func factoryMethod () -> Product } class ConcreteCreatorA : Creator {     func factoryMethod () -> Product { return ConcreteProductA () } } class ConcreteCreatorB : Creator {     func factoryMethod () -> Product { return ConcreteProductB () } } let creatorA = ConcreteCreatorA () let creatorB = ConcreteCreatorB () hagyjuk az alkotókat : [ Creator ] = [ CreatorA , CreatorB ] alkotók . forEach {     let product = 0 $ . factoryMethod () print ( product . getName ()) }    

Python

Példa Pythonban # kódolás: utf-8 """Tuning típusok""" osztály Kultúra : """Kultúra""" def __repr__ ( self ): return self . __str__ () osztály Demokrácia ( kultúra ): def __str__ ( self ): return 'Demokrácia' osztály Diktatúra ( Kultúra ): def __str__ ( self ): return 'Diktatúra' class Kormányzat : """Maga a kormányzat""" kultúra = '' def __str__ ( self ): return self . kultúra . __str__ () def __repr__ ( self ): önmagát adja vissza . kultúra . __repr__ () def set_culture ( self ): """Set build to Government : ez a mi gyári módszerünk""" AttributeError ( ' Nem implementált kultúra' ) osztály GovernmentA ( Government ): def set_culture ( self ): self . kultúra = demokrácia () osztály KormányzatB ( Kormányzat ): def set_culture ( self ): self . kultúra = diktatúra () g1 = KormányzatA () g1 . set_culture () print ( str ( g1 )) g2 = KormányB () g2 . set_culture () print ( str ( g2 ))

Java

Java példa interfész Termék { } osztály ConcreteProductA megvalósítja a terméket { } osztály ConcreteProductB megvalósítja a terméket { } abstract class Creator { public abstract Product factoryMethod (); } class ConcreteCreatorA extends Creator { @Override public Product factoryMethod () { return new ConcreteProductA (); } } class ConcreteCreatorB expands Creator { @A public Override Product factoryMethod () { return new ConcreteProductB (); } } public class FactoryMethodExample { public static void main ( String [] args ) { // alkotók tömbje Creator [] creators = { new ConcreteCreatorA (), new ConcreteCreatorB ()}; // iterál az alkotók között, és hozzon létre termékeket a következőhöz: ( Creator creator : creators ) { Product product = creator . gyári módszer (); Rendszer . ki . printf ( "Létrehozva {%s}\n" , termék .getClass ( )); } } }

A munka eredménye:

Létrehozva: {class ConcreteProductA} Létrehozva: {class ConcreteProductB}

C++

Példa C++ nyelven #include <iostream> #include <karakterlánc> névtér használata std ; struct termék { virtuális karakterlánc getName () = 0 ; virtuális ~ termék (){} }; struct ConcreteProductA : Termék { string getName (){ return "ConcreteProductA" ;} }; struct ConcreteProductB : Termék { string getName (){ return "ConcreteProductB" ;} }; struct Creator { virtuális termék * gyári módszer () = 0 ; }; struct ConcreteCreatorA : Creator { Product * factoryMethod (){ return new ConcreteProductA ();} }; struct ConcreteCreatorB : Creator { Product * factoryMethod (){ return new ConcreteProductB ();} }; int main () { ConcreteCreatorA CreatorA ; ConcreteCreatorB CreatorB ; // Alkotók tömbje Creator * creators [] = { & CreatorA , & CreatorB }; // Iteráció az alkotók között, és hozzon létre termékeket ( auto && creator : creators ) { Termék * termék = alkotó -> gyári módszer (); cout << termék -> getName () << endl ; termék törlése ; } return 0 ; }

A munka eredménye:
ConcreteProductA
ConcreteProductB

C#

Példa a C# -ban a rendszer használatával ; a System.Collections.Generic használatával ; névtér Gyári { public abstract class Product { public abstract string GetType (); } public class ConcreteProductA : Termék { public override string GetType () { return "ConcreteProductA" ; } } public class ConcreteProductB : Termék { public override string GetType () { return "ConcreteProductB" ; } } public abstract class Creator { public abstract Product FactoryMethod (); } public class ConcreteCreatorA : Alkotó { public override Product FactoryMethod () { return new ConcreteProductA (); } } public class ConcreteCreatorB : Alkotó { public override Product FactoryMethod () { return new ConcreteProductB (); } } public static class MainApp { public static void Main () { // alkotók tömbje Alkotó [] creators = { new ConcreteCreatorA (), new ConcreteCreatorB () }; // iteráció az alkotók felett és termékek létrehozása foreach ( Creator creator az alkotókban ) { Product product = creator . Gyári módszer (); Konzol . WriteLine ( "Létrehozva {0}" , termék .GetType ( )); } // Várjon a felhasználói konzolra . olvasni (); } } }

JavaScript

JavaScript ES5 példa var NewConcreteCreatorA = ()=>{ return { factoryMethod : ()=>{ return { getName : ()=> "ConcreteProductA" };}} }; var NewConcreteCreatorB = ()=>{ return { factoryMethod : ()=>{ return { getName : ()=> "ConcreteProductB" };}} }; var creators = [ NewConcreteCreatorA (), NewConcreteCreatorB ()]; alkotók . map ( creator => console . log ( creator . factoryMethod (). getName ())); JavaScript ES6 példa osztály Termék { GetName () {} } class ConcreteProductA kiterjeszti a terméket { GetName () { return 'ProductA' } } class ConcreteProductB kiterjeszti a terméket { GetName () { return 'ProductB' } } class Creator { FactoryMethod () {} } class ConcreteCreatorA kiterjeszti a Creatort { FactoryMethod () { return new ConcreteProductA () } } class ConcreteCreatorB kiterjeszti a Creator { FactoryMethod () { return new ConcreteProductB () } } // Alkotók tömbje const creators = [ new ConcreteCreatorA (), new ConcreteCreatorB () ] const products = [] // Iteráljon az alkotók között, és hozzon létre termékeket ( engedjük meg az alkotókat ) { products . push ( creator.FactoryMethod ( ). getName ( )) } konzol . napló ( termékek ) Példa TypeScriptben interfész Termék { GetName () : string } class ConcreteProductA megvalósítja a terméket { public GetName () { return 'ProductA' } } class ConcreteProductB implements Product { public GetName () { return 'ProductB' } } felület létrehozója { Gyári módszer () : Termék } class ConcreteCreatorA implementálja a Creatort { public FactoryMethod () { return new ConcreteProductA () } } class ConcreteCreatorB implementálja a Creatort { public FactoryMethod () { return new ConcreteProductB () } } // Alkotók tömbje const creators : Creator [] = [ new ConcreteCreatorA (), new ConcreteCreatorB () ] const products : string [] = [] // Iteráljon az alkotók között, és hozzon létre termékeket ( engedjük meg az alkotókat ) { products . push ( creator.FactoryMethod ( ). getName ( )) } konzol . napló ( termékek )

PHP5

PHP példa <?php interfész Termék { public function GetName (); } class ConcreteProductA implements Product { public function GetName () { return "ProductA" ; } } class ConcreteProductB implements Product { public function GetName () { return "TermékB" ; } } interface Creator { public function FactoryMethod (); } class ConcreteCreatorA implements Creator { public function FactoryMethod () { return new ConcreteProductA (); } } class ConcreteCreatorB implements Creator { public function FactoryMethod () { return new ConcreteProductB (); } } // Alkotók tömbje $creators = array ( new ConcreteCreatorA (), new ConcreteCreatorB () ); // Iteráljon az alkotók között és hozzon létre termékeket foreach ( $creators mint $creator ) { $termékek [] = $creator -> FactoryMethod () -> getName (); } header ( "content-type:text/plain" ); echo var_export ( $termékek ); ?>

PHP5 modern verzió

A PHP -ben leggyakrabban használt minta rövidített változata <?php /** * Class Animal, több mint 20 éve a könyv első kiadása óta, és ez a minta egy kicsit fejlődött, * és most mindig a rövidített formáját használja */ abstract class Animal { // gyári metódus, amely egy objektum típusa alapján public static function iniciális ( $állat ) { return new $animal (); } absztrakt nyilvános funkció hangja (); } class Lion extends Animal { public function voice () { echo 'Rrrrrrr i\'m the lion <br />' . PHP_EOL ; } } class Cat extends Animal { public function voice () { echo 'Miau, miau én vagyok a cica <br />' . PHP_EOL ; } } $állat1 = Állat :: kezdeti ( 'Oroszlán' ); $állat2 = Állat :: kezdeti ( 'Macska' ); $állat1 -> hang (); $állat2 -> hang ();

Delphi

Delphi példa program FactoryMethod ; {$APPTYPE CONSOLE} SysUtils-t használ ; típus // Termék TProduct = class ( TObject ) public function GetName : string ; virtuális ; absztrakt ; vége ; // ConcreteProductA TConcreteProductA = class ( TProduct ) nyilvános függvény GetName : string ; felülbírálni ; vége ; // ConcreteProductB TConcreteProductB = class ( TProduct ) nyilvános függvény GetName : string ; felülbírálni ; vége ; // Létrehozó TCreator = class ( TObject ) nyilvános függvény FactoryMethod : TProduct ; virtuális ; absztrakt ; vége ; // ConcreteCreatorA TConcreteCreatorA = osztály ( TCreator ) nyilvános függvény FactoryMethod : TProduct ; felülbírálni ; vége ; // ConcreteCreatorB TConcreteCreatorB = osztály ( TCreator ) nyilvános függvény FactoryMethod : TProduct ; felülbírálni ; vége ; { ConcreteProductA } function TConcreteProductA . GetName : string ; begin Eredmény := 'ConcreteProductA' ; vége ; { ConcreteProductB } function TConcreteProductB . GetName : string ; begin Eredmény := 'ConcreteProductB' ; vége ; { ConcreteCreatorA } function TConcreteCreatorA . Gyári módszer : TTermék ; begin Eredmény := TConcreteProductA . létrehozni ; vége ; { ConcreteCreatorB } function TConcreteCreatorB . Gyári módszer : TTermék ; begin Eredmény := TConcreteProductB . létrehozni ; vége ; const Szám = 2 ; var Létrehozók : a Tcreator tömbje [ 1 .. Count ] ; Termék : TProduct ; I : Integer ; begin // Alkotók tömbje Alkotók [ 1 ] := TConcreteCreatorA . létrehozni ; Alkotók [ 2 ] := TConcreteCreatorB . létrehozni ; // Iteráljon az alkotók között, és hozzon létre termékeket az I := 1 -hez a Count do begin Product := Alkotók [ I ] számára . Gyári módszer ; WriteLn ( Termék . GetName ) ; termék . Ingyenes ; vége ; mert I : = 1 Count do Alkotók [ I ] . Ingyenes ; Readln ; vége . Delphi példa (virtuális konstruktorok) program FactoryMethod ; {$APPTYPE CONSOLE} SysUtils-t használ ; típus // Termék TProduct = class ( TObject ) private SubName : string ; public function GetName : string ; virtuális ; absztrakt ; function GetFullName : string ; konstruktor Create ; virtuális ; absztrakt ; vége ; TProductClass = a TProduct osztálya ; // ConcreteProductA TConcreteProductA = class ( TProduct ) nyilvános függvény GetName : string ; felülbírálni ; konstruktor Create ; felülbírálni ; vége ; // ConcreteProductB TConcreteProductB = class ( TProduct ) nyilvános függvény GetName : string ; felülbírálni ; konstruktor Create ; felülbírálni ; vége ; { TTermék} függvény TTermék . GetFullName : string ; begin Eredmény := GetName + ' : ' + Alnév ; vége ; { ConcreteProductA } konstruktor TConcreteProductA . létrehozni ; kezd örökölt ; SubName := 'A termék alneve' ; vége ; függvény TConcreteProductA . GetName : string ; begin Eredmény := 'ConcreteProductA' ; vége ; { ConcreteProductB } konstruktor TConcreteProductB . létrehozni ; kezd örökölt ; SubName := 'B termék alneve' ; vége ; függvény TBetontermékB . GetName : string ; begin Eredmény := 'ConcreteProductB' ; vége ; const Szám = 2 ; var Létrehozók : TProductClass tömb [ 1 .. Count ] ; _ Termék : TProduct ; I : Integer ; begin // Alkotók tömbje Alkotók [ 1 ] := TConcreteProductA ; Alkotók [ 2 ] := TConcreteProductB ; // Iteráljon az alkotók között, és hozzon létre termékeket az I := 1 -hez a Count do begin Product := Alkotók [ I ] számára . létrehozni ; WriteLn ( Termék . GetFullName ) ; termék . Ingyenes ; vége ; Readln ; vége .

Action Script 3.0

Példa az Action Script 3.0 -ban protected class Létrehozó { Protected function factoryMethod () : Termék { return null ; } public function someFunction () : void { var _product : Product = factoryMethod (); _termék . doSome (); } } public class ConcreteCreatorA extends Creator { override protected function factoryMethod () : Product { return new ConcreteProductA (); } } public class ConcreteCreatorB extends Creator { override protected function factoryMethod () : Product { return new ConcreteProductB (); } } nyilvános felület Termék { function doSome () : void {} } belső osztály ConcreteProductA megvalósítja a terméket { public function doSome () : void {} } belső osztály ConcreteProductB megvalósítja a terméket { public function doSome () : void {} } // MEGVALÓSÍTÁS public class Main { public function Main () { var _creatorA : ConcreteCreatorA = new ConcreteCreatorA (); _creatorA . someFunction (); var _creatorB : ConcreteCreatorB = new ConcreteCreatorB (); _creatorB . someFunction (); } }

scala

Scala példa absztrakt osztály _ _ def getName : String } absztrakt osztály _ _ def getProduct : AbstractProduct } class Beer extends AbstractProduct { def getName felülírása : String = "Sör" } class Wine extends AbstractProduct { def getName felülírása : String = "Bor" } class BeerCreator kiterjeszti az AbstractCreator { def getProduct felülírása : AbstractProduct = új sör } class WineCreator kiterjeszti az AbstractCreator { def getProduct felülírása : AbstractProduct = új bor } Object Test { private def printProductName ( készítő : AbstractCreator ) : Unit = println ( creator . getProduct . getName ) def main ( args : Array [ String ] ) : Unit = printProductName ( new BeerCreator ) printProductName ( new WineCreator ) }

Munka eredménye:
Készült: Bor Létrehozva: Sör

Ruby

Példa Rubyban modul FactoryMethod # Termékosztály Termék attr_reader : productType def inicializálás @productType = nil end end # ConcreteProductA osztály ConcreteProductA < Product attr_reader :productType def inicialize @productType = "ConcreteProductA" end end # ConcreteProductB class ConcreteProductB < Product attr_reader :productType def inicialize @productType = "ConcreteProductB" end end # Creator class Creator def factoryMethod termék . új vég vége # ConcreteCreatorA class ConcreteCreatorA < Creator def factoryMethod ConcreteProductA . új vég vége # ConcreteCreatorB class ConcreteCreatorB < Creator def factoryMethod ConcreteProductB . new end end end # Kliens modul Az ügyfél tartalmazza a FactoryMethodot creators = [ ConcreteCreatorA . új , ConcreteCreatorB . új ] alkotók . mindegyik do | alkotó | elhelyezi : " #{ creator . class } create Product: \t #{ creator . factoryMethod . productType } " end # => FactoryMethod::ConcreteCreatorA Create Product: ConcreteProductA # => FactoryMethod::ConcreteCreatorB Create Product: ConcreteProductB end

Irodalom

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides . Objektumorientált tervezés technikái. Tervezési minták = Tervezési minták : Az újrafelhasználható objektum-orientált szoftver elemei. - Szentpétervár. : "Péter" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . ( ISBN 5-272-00355-1 is )