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:
- az osztály nem tudja előre, hogy mely alosztályok melyik objektumait kell létrehoznia.
- egy osztály úgy van kialakítva, hogy az általa létrehozott objektumokat alosztályok határozzák meg.
- az osztály feladatait a több segítő alosztály valamelyikére delegálja, és a tervek szerint lokalizálják, hogy melyik osztály veszi át ezeket a feladatokat.
Szerkezet
- termék - termék
- interfészt definiál az absztrakt módszerrel létrehozott objektumok számára;
- ConcreteProduct - egy adott termék
- megvalósítja a Termék interfészt ;
- alkotó _
- deklarál egy gyári metódust, amely egy Product típusú objektumot ad vissza . Tartalmazhatja a módszer "alapértelmezett" megvalósítását is;
- hívhat egy gyári metódust egy Product típusú objektum létrehozásához ;
- ConcreteCreator – konkrét alkotó
- felülírja a gyári metódust a ConcreteProduct osztály objektumának létrehozásához és visszaadásához .
Előnyök
- lehetővé teszi az objektumok létrehozására szolgáló kód univerzálisabbá tételét, amely nem kötődik meghatározott osztályokhoz (ConcreteProduct), hanem csak közös felülettel (Product) működik;
- lehetővé teszi a párhuzamos osztályhierarchiák közötti kapcsolat létrehozását.
Hátrányok
- annak szükségessége, hogy minden új terméktípushoz (ConcreteProduct) létrejöjjön egy Creator utód.
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 )