Prototípus (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 2016. március 9-én felülvizsgált
verziótól ; az ellenőrzések 11 szerkesztést igényelnek .
Prototípus , ( eng. Prototype ) - generáló tervezési minta .
Időpont
Meghatározza a prototípuspéldány használatával létrehozandó objektumok típusait, és ennek a prototípusnak a másolásával hoz létre új objektumokat. Lehetővé teszi, hogy eltávolodjon a megvalósítástól, és lehetővé teszi az „interfészeken keresztüli programozás” elvének követését. A hierarchia tetején lévő interfész/absztrakt osztály van megadva visszatérő típusként, és a leszármazott osztályok helyettesíthetnek egy örököst, amely ezt a típust megvalósítja.
Egyszerűen fogalmazva, ez egy objektum létrehozásának mintája egy másik objektum klónozásával, ahelyett, hogy egy konstruktoron keresztül hozná létre.
Alkalmazás
A mintát a következőkre használják:
- elkerülni a további erőfeszítéseket egy objektum szabványos módon történő létrehozására (értsd a konstruktor használatát, mivel ebben az esetben az objektum elődeinek teljes hierarchiájának konstruktorait is hívják), amikor ez az alkalmazás számára megfizethetetlenül költséges.
- kerülje az objektum létrehozójának öröklését az ügyfélalkalmazásban, ahogy az absztrakt gyári minta teszi .
Használja ezt a tervezési mintát, ha a rendszert nem érdekli a termékek létrehozása, csomagolása és bemutatása:
- a példányosított osztályokat futási időben határozzák meg, például dinamikus betöltéssel;
- kerülje a termékosztály-hierarchiával párhuzamos osztályhierarchiák vagy gyárak építését;
- Az osztálypéldányok többféle állapotúak lehetnek. Kényelmesebb lehet a megfelelő számú prototípus beállítása és klónozása, ahelyett, hogy minden alkalommal manuálisan példányosítanánk az osztályt a megfelelő állapotban.
Példák
Python példa
Forráskód Pythonban
#!/usr/bin/env python
# -*- kódolás: utf-8 -*-
import másolatot
osztály prototípusa :
def __init__ ( self ):
én . _objects = {}
def register_object ( self , name , obj ):
"""Objektum regisztrálása"""
self . _objektumok [ név ] = objektum
def unregister_object ( self , name ):
"""Objektum regisztrációjának törlése"""
del self . _objects [ név ]
def clone ( self , name , ** attr ):
"""Regisztrált objektum klónozása és a belső attribútumok szótárának frissítése"""
obj = copy . mélymásolat ( self . _objects . get ( név ))
obj . __dikt__ . frissítés ( attr )
return obj
osztály A :
def __init__ ( self ):
self . x = 3
én . y = 8
self . z = 15
én . szemét = [ 38 , 11 , 19 ]
def __str__ ( self ):
return ' {} {} {} {} ' . formátum ( self . x , self . y , self . z , saját . szemét )
def main ():
a = A ()
prototype = Prototype ()
prototype . register_object ( 'objektum' , a )
b = prototípus . klón ( 'objektum' )
c = prototípus . klón ( 'objektum' , x = 1 , y = 2 , szemét = [ 88 , 1 ])
print ([ str ( i ) for i in ( a , b , c )])
if __name__ == '__main__' :
fő ()
- KIMENET ###
- ['3 8 15 [38, 11, 19]", "3 8 15 [38, 11, 19]", "1 2 15 [88, 1]"]
C++ példa
Forrásszöveg C++ nyelven
osztály étkezés {
nyilvános :
virtuális ~ étkezés ();
virtuális void eat () = 0 ;
virtuális étkezés * klón () const = 0 ;
//...
};
osztály Spagetti : nyilvános étkezés {
nyilvános :
Spagetti ( const Spaghetti & );
void eat ();
Spagetti * clone () const { return new Spaghetti ( * this ); }
//...
};
Java példa
Java forrás
/**
* Prototype Class
*/
public class Cookie - k klónozható {
védett belső tömeg ;
@Override
public Cookie klón () dobja a CloneNotSupportedException {
Cookie copy = ( Cookie ) super . klón ();
//Ennek a mintának a tényleges megvalósításában most megváltoztathatja a hivatkozásokat a
//a prototípuson belül tárolt másolatokból drága alkatrészekre.
vissza másolat ;
}
}
/**
* Klónozandó konkrét prototípusok
*/
public class CoconutCookie kiterjeszti a cookie -t { }
/**
* Ügyfélosztály
*/
public class CookieMachine {
privát Cookie cookie ; // Lehetett egy privát klónozható süti.
public CookieMachine ( Cookie cookie ) {
this . süti = süti _
}
public Cookie makeCookie () dobja a CloneNotSupportedException {
return ( Cookie ) this . süti . klón ();
}
public static void main ( String args [ ] ) throws CloneNotSupportedException {
Cookie tempCookie = null ;
Cookie prot = új CoconutCookie ();
CookieMachine cm = új CookieMachine ( prot );
for ( int i = 0 ; i < 100 ; i ++ )
tempCookie = cm . makeCookie ();
}
}
Scala példa
Scala forráskód
package.com _
csomag objektum prototípus {
class Waffle (
Protected var name : String ,
protected var primerFilling : String ,
protected var specialFilling : Option [ String ] = Nincs
)
extends Klónozható {
def klón felülírása (): Waffle = {
szuper . klón (). mint InstanceOf [ Waffle ]
}
def output () : Unit = {
println ( s" Otya $ név elsődleges töltettel $ elsődleges kitöltés " + ( if ( specialFilling != None ) specialFilling . get else "" )) } }
object PrototypeTest {
def main ( args : Array [ String ]) : Unit = {
println ( "Kimenet:" )
val chocolateWaffle = new Waffle ( "ChocolateWaffle" , "Csokoládé" )
chocolateWaffle . kimenet ()
csokoládé Gofri . klón (). output ()
val coconutWaffle = új Gofri ( "CoconutWaffle" , " Condensed milk" , Some ( "Coconut" ) )) coconutWaffle . output () coconutWaffle . klón (). kimenet () } } }
// Kimenet:
// Gofri Csokoládé Gofri elsődleges töltelékkel Csokoládé // Gofris Csokoládé Gofri
elsődleges töltelékkel Csokoládé
// Gofris Kókuszos gofri elsődleges töltelékkel Sűrített tej Kókusz
// Gofri Kókuszos gofri elsődleges töltelékkel Sűrített tej Kókuszos
Példa C#-ban
Forrásszöveg C# nyelven
a rendszer használatával ;
névtér Prototípus
{
class MainApp
{
static void Main ()
{
// Hozzon létre két példányt, és klónozza mindegyik
prototípust prototípus1 = new ConcretePrototype1 ( "I" );
Prototype clonedPrototype1 = prototípus1 . klón ();
Konzol . WriteLine ( "Klón: {0}" , klónozottPrototípus1 . Id );
Prototype prototype2 = new ConcretePrototype2 ( "II" );
Prototype clonedPrototype2 = prototípus2 . klón ();
Konzol . WriteLine ( "Klónozott: {0}" , klónozottPrototípus2 . Id );
}
}
// "Prototípus"
public abstract class Prototype
{
// Konstruktor
public Prototype ( string id )
{
this . id = id ;
Konzol . Write ( "Az alapkonstruktort hívják." );
}
// Property
public string Id { get ; magánkészlet ; _ }
nyilvános virtuális prototípus klón ()
{
// Sekély másolás
visszatér ( Prototype ) this . MemberwiseClone ();
}
}
// "ConcretePrototype1"
public class ConcretePrototype1 : Prototype
{
// Konstruktor
public ConcretePrototype1 ( string id ) : base ( id )
{
}
}
// "ConcretePrototype2"
public class ConcretePrototype2 : Prototype
{
// Konstruktor
public ConcretePrototype2 ( string id ) : base ( id )
{
}
}
}
PHP példa
PHP forráskód
<?php
/**
* A prototípuskészítés érvényes osztályainak hierarchiája
*/
absztrakt osztály Terep {}
absztrakt osztály Tenger kiterjed Terep {}
osztály FöldTenger kiterjeszti Tenger {}
osztály MarsTenger kiterjeszti Tenger {}
osztály Vénusz Tenger kiterjeszti Tenger {}
absztrakt osztály Síkság kiterjedés Terep {} osztály EarthPlains kiterjedés Síkság {} osztály MarsPlains kiterjedés Síkság {} osztály VenusPlains kiterjedés Síkság {}
absztrakt osztály Erdő kiterjeszti Terep {}
osztály FöldErdő kiterjed Erdő { }
osztály MarsForest kiterjeszti Erdő {}
osztály VénuszErdő kiterjeszti Erdő {}
/**
* Prototípus gyári logika meghatározása
*/
class TerrainFactory {
private $tenger ;
magán $erdő ;
privát $plains ;
public function __construct ( Tenger $tenger , Síkság $síkság , Erdő $ erdő ) { $this -> tenger = $tenger ; $this -> plains = $plains ; $ez -> erdő = $erdő ; } function getSea ( ) { return klón $this -> sea ; } function getPlains ( ) { return klón $this -> plains ; } function getForest ( ) { return klón $this -> forest ; } }
/**
* Gyár létrehozása a megadott prototípus paraméterekkel
*/
$prototypeFactory = new TerrainFactory (
new EarthSea (),
new MarsPlains (),
new VenusForest ()
);
/**
* A megadott objektumok létrehozása klónozással
*/
$tenger = $prototypeFactory -> getSea ();
$plains = $prototypeFactory -> getPlains ();
$erdő = $prototypeFactory -> getForest ();
Példa a Rubyban
Ruby forráskód
modul prototípusa
# "prototípus"
osztályú prototípus
# Property
# az id tulajdonság kezdetben minden objektumnál jelen van, ezért a name property-t fogjuk használni
attr_reader :név
#konstruktor
def inicializálja a nevet
@ név = név
vége
vége
vége
# Hozzon létre egy példányt és klónozza azt
p1 = Prototype :: Prototype . new "my name" # a Prototype osztály objektuma a hagyományos módon jön létre - new
p2 = p1 metódussal . clone # a klónozási metódus alapértelmezés szerint minden objektumon létezik – nem kell definiálni
puts "p1.id = #{ p1 . object_id } , p2.id = #{ p2 . object_id } " # különböző azonosítók kerülnek kinyomtatásra
helyezi "p1.name = #{ p1 . name } , p2.name = #{ p2 . név } " # azonos név kerül kinyomtatásra - "a nevem"
# Várja meg, amíg a felhasználó
megkapja
VB.NET példa
Forrásszöveg VB.NET nyelven
Névtér prototípus
osztály MainApp
Shared Sub Main ()
Hozzon létre két példányt, és mindegyiket klónozza
Dim p1 As Prototype = New ConcretePrototype1 ( "I" )
Dim c1 As Prototype = p1 . Konzol klónozása ()
. WriteLine ( "Klón: {0}" , c1 . Id )
Dim p2 As Prototype = New ConcretePrototype2 ( "II" )
Dim c2 As Prototype = p2 . Konzol klónozása ()
. WriteLine ( "Klón: {0}" , c2 . Id )
Konzol . Olvassa el ()
End Sub
End Class
"Prototípus"
Inherit Class Prototype
Private m_id As String
' Constructor
Public Sub New ( ByVal id As String )
Me . m_id = id
End Sub
Nyilvános , csak olvasható tulajdonságazonosító ( ) karakterláncként Get Return m_id End Get End Property
Public MustOverride Function Clone ( ) Prototype End Classként
' "ConcretePrototype1"
Osztály ConcretePrototype1
Örökli a Prototype
'Constructor
Public Sub New ( ByVal id As String )
MyBase . Új ( id )
End Sub
Nyilvános felülbírálja a függvény klónozását () prototípusként ' Hiányos másolat Vissza DirectCast ( Me . MemberwiseClone ( ), Prototípus ) Funkció vége End Class
"ConcretePrototype2"
A ConcretePrototype2
osztály örökli a prototípust
' Constructor
Public Sub New ( ByVal id As String )
MyBase . Új ( id )
End Sub
Nyilvános felülbírálja a függvény klónozását () prototípusként ' Hiányos másolat Vissza DirectCast ( Me . MemberwiseClone ( ) , Prototípus ) Funkció vége End Class End névtér
Delphi példa
Forrásszöveg Delphiben
program PrototypePattern ;
{$APPTYPE CONSOLE}
SysUtils-t használ ;
type
TPrototype = osztály
public
function Klón : TPrototype ; virtuális ; absztrakt ;
vége ;
típus
TPrototypeType = osztály ( TPotípus )
privát
FID : Integer ;
FInfo : String ;
public
property ID : Integer olvasás FID írás FID ;
tulajdonság Info : String beolvasás FIinfo írás FIinfo ;
funkció Klón : TPrototype ; felülbírálni ;
vége ;
függvény TPrototypeType . Klón : T prototípus ;
var
vClone : TPrototypeType ;
begin
vClone := TPrototypeType . létrehozni ;
vClone . ID := ID ;
vClone . Info := Info ;
Eredmény := vClone ;
vége ;
eljárás CloneAndShow ( Prototípus : TPrototypeType ) ;
var
vClone : TPrototypeType ;
begin
vClone := Prototype . klón ;
try
Write ( vClone . ID ) ;
Írás ( vClone.Info ) ; _ _ végül vClone . Ingyenes ; vége ;
WriteLn ;
vége ;
var
vConcretePrototype1 , vConcretePrototype2 : TPrototypeType ;
begin
vConcretePrototype1 := TPrototypeType . létrehozni ;
vConcretePrototype2 := TPrototypeType . létrehozni ;
próbáld
ki a vConcretePrototype1-et . ID := 10 ;
vConcretePrototype1 . Info := 'Prototype1!' ;
vConcretePrototype2 . ID := 11 ;
vConcretePrototype2 . Info := 'Prototípus2!' ;
CloneAndShow ( vConcretePrototype1 ) ;
CloneAndShow ( vConcretePrototype2 ) ;
végül
vConcretePrototype1 . Ingyenes ;
vConcretePrototype2 . Ingyenes ;
vége ;
Readln ;
vége .
CoffeeScript példa
CoffeeScript példa
osztály elnökPrototípus
konstruktor: (@proto) ->
klón: ->
ügyfél = új elnök ()
customer.first = @proto . first
customer.last = @proto . utolsó ügyfél.aka
= @proto . más néven
ügyfél
osztály elnök
konstruktor: (@első, @utolsó, @aka) ->
mondd: -> konzol . log "A neve #{ @first } #{ @last } aka #{ @aka } ."
run = ->
proto = új elnök ( "Jimmy" , "Wales" , "Jimbo" )
prototípus = új elnökPrototípus ( proto )
ügyfél = prototípus . klón ()
ügyfél . mondd ()
futni ()
Io példa
Io forráskód
Foo := Objektum klón
Foo smth := 2
Bar := Foo klón
Irodalom
- E. Gamma, R. Helm, R. Johnson, J. Vlissides . Objektumorientált tervezés technikái. Tervezési minták = Design Patterns: 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 )
Lásd még
Linkek