Prototype (designmønster)

Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den version , der blev gennemgået den 9. marts 2016; checks kræver 11 redigeringer .
Prototype
prototype
Type genererer
Beskrevet i Design Patterns Ja

Prototype , ( eng.  Prototype )  -genererende designmønster .

Udnævnelse

Angiver den slags objekter, der skal oprettes ved hjælp af en prototypeinstans og opretter nye objekter ved at kopiere denne prototype. Det giver dig mulighed for at komme væk fra implementeringen og giver dig mulighed for at følge princippet om "programmering gennem grænseflader". En grænseflade/abstrakt klasse øverst i hierarkiet er angivet som den returnerende type, og efterkommerklasser kan erstatte en arving, der implementerer denne type der.

Kort sagt er dette mønsteret for at skabe et objekt ved at klone et andet objekt i stedet for at skabe det gennem en konstruktør.

Ansøgning

Mønsteret bruges til at:

Brug dette designmønster, når systemet er ligeglad med, hvordan produkter skabes, pakkes og præsenteres i det:

Eksempler

Python-eksempel

Kildekode i Python #!/usr/bin/env python # -*- kodning: utf-8 -*- import kopi klasse prototype : def __init__ ( selv ): selv . _objekter = {} def register_object ( selv , navn , obj ): """Registrer et objekt""" selv . _objekter [ navn ] = obj def unregister_object ( selv , navn ): """Afregistrer et objekt""" del selv . _objekter [ navn ] def clone ( selv , navn , ** attr ): """Klon et registreret objekt og opdater indre attributordbog""" obj = kopi . deepcopy ( selv . _objekter . ( navn )) obj . __dikt__ . opdatere ( attr ) returnere obj klasse A : def __init__ ( selv ): selv . x = 3 selv . y = 8 selv . z = 15 selv . skrald = [ 38 , 11 , 19 ] def __str__ ( selv ): returner ' {} {} {} {} ' . format ( selv . x , selv . y , selv . z , selv . skrald ) def main (): a = A () prototype = Prototype () prototype . register_object ( 'objecta' , a ) b = prototype . klon ( 'objecta' ) c = prototype . clone ( 'objecta' , x = 1 , y = 2 , garbage = [ 88 , 1 ]) print ([ str ( i ) for i in ( a , b , c )]) if __name__ == '__main__' : main ()
      1. OUTPUT ###
  1. ['3 8 15 [38, 11, 19]', '3 8 15 [38, 11, 19]', '1 2 15 [88, 1]']

C++ eksempel

Kildetekst i C++ klasse måltid { offentligt : virtuelt ~ måltid (); virtual void eat () = 0 ; virtuelt måltid * klon () const = 0 ; //... }; klasse Spaghetti : offentligt måltid { offentligt : Spaghetti ( konst Spaghetti & ); void spise (); Spaghetti * clone () const { returnere ny Spaghetti ( * this ); } //... };

Java-eksempel

Java kilde /** * Prototype Klasse */ offentlig klasse Cookie implementerer Klonbar { beskyttet int vægt ; @Override public Cookie klon () kaster CloneNotSupportedException { Cookie copy = ( Cookie ) super . klon (); //I en faktisk implementering af dette mønster kan du nu ændre referencer til //det dyre at producere dele fra de kopier, der opbevares inde i prototypen. returnere kopi ; } } /** * Konkrete prototyper til kloning */ offentlig klasse CoconutCookie udvider Cookie { } /** * Klientklasse */ offentlig klasse CookieMachine { privat Cookie- cookie ; // Kunne have været en privat kloningsbar cookie. offentlig CookieMachine ( Cookie - cookie ) { dette . cookie = cookie _ } public Cookie makeCookie () kaster CloneNotSupportedException { returner ( Cookie ) dette . cookie . klon (); } public static void main ( String args [] ) kaster CloneNotSupportedException { Cookie tempCookie = null ; Cookie prot = ny CoconutCookie (); CookieMachine cm = ny CookieMachine ( prot ); for ( int i = 0 ; i < 100 ; i ++ ) tempCookie = cm . laveCookie (); } }

Scala eksempel

Scala kildekode package.com _ pakkeobjekt prototype { _ class Waffle ( protected var name : String , protected var primaryFyld : String , protected var specialFilling : Option [ String ] = Ingen ) udvider Cloneable { tilsidesæt def klon (): Vaffel = { super . klon (). asInstanceOf [ Waffle ] } def output () : Enhed = { println ( s"Waffle $ navn med primær fyldning $ primaryFyld " + ( if ( specialFyld != Ingen ) specialFyld . get else "" )) } } objekt PrototypeTest { def main ( args : Array [ String ]) : Enhed = { println ( "Output:" ) val chocolateWaffle = new Waffle ( "ChocolateWaffle" , "Chocolate" ) chocolateWaffle . output () chokoladeVaffel . klon (). output () val coconutWaffle = new vaffel ( "CoconutWaffle" , "Kondenseret mælk" , Nogle ( "Coconut" ) )) coconutWaffle . output () coconutWaffle . klon (). output () } } } // Output: // VaffelchokoladeVaffel med primært fyld Chokolade // VaffelchokoladeVaffel med primært fyld Chokolade // Vaffel KokosVaffel med primært fyld Kondenseret mælkKokos // Vaffel KokosVaffel med primært fyld Kondenseret mælkKokosnød

Eksempel i C#

Kildetekst i C# bruger System ; namespace Prototype { class MainApp { static void Main () { // Opret to forekomster og klon hver Prototype prototype1 = new ConcretePrototype1 ( "I" ); Prototype clonedPrototype1 = prototype1 . klon (); Konsol . WriteLine ( "Clone: ​​​​{0}" , clonedPrototype1 . Id ); Prototype prototype2 = ny ConcretePrototype2 ( "II" ); Prototype clonedPrototype2 = prototype2 . klon (); Konsol . WriteLine ( "Klonet: {0}" , klonet Prototype2 . Id ); } } // "Prototype" public abstract class Prototype { // Constructor public Prototype ( string id ) { this . id = id ; Konsol . Skriv ( "Base constructor kaldes." ); } // Property public string Id { get ; privat sæt ; } public virtual Prototype Clone () { // Shallow copy return ( Prototype ) this . MemberwiseClone (); } } // "ConcretePrototype1" public class ConcretePrototype1 : Prototype { // Constructor public ConcretePrototype1 ( string id ) : base ( id ) { } } // "ConcretePrototype2" public class ConcretePrototype2 : Prototype { // Constructor public ConcretePrototype2 ( string id ) : base ( id ) { } } }

PHP eksempel

PHP kildekode

<?php /** * Hierarki af gyldige klasser til prototyping */ abstrakt klasse Terræn {} abstrakt klasse Hav udvider Terræn {} klasse JordHav udvider Hav {} klasse MarsHav udvider Hav {} klasse VenusHav udvider Hav {} abstrakt klasse Plains udvider Terræn {} klasse EarthPlains udvider Plains {} klasse MarsPlains udvider Plains {} klasse VenusPlains udvider Plains {} abstrakt klasse Skov udvider Terræn {} klasse EarthForest udvider Skov {} klasse MarsForest udvider Skov {} klasse VenusForest udvider Skov {} /** * Definer prototype fabrikslogik */ klasse TerrainFactory { private $sea ; privat $skov ; private $sletten ; public function __construct ( Hav $sea , Plains $plains , Forest $forest ) { $this -> sea = $sea ; $this -> plains = $plains ; $dette -> skov = $skov ; } funktion getSea ( ) { return clone $this -> sea ; } funktion getPlains ( ) { return clone $this -> plains ; } funktion getForest ( ) { return clone $this -> forest ; } } /** * Opret en fabrik med de givne prototypeparametre */ $prototypeFactory = ny TerrainFactory ( ny EarthSea (), ny MarsPlains (), ny VenusForest () ); /** * Opret de givne objekter ved at klone */ $sea = $prototypeFactory -> getSea (); $plains = $prototypeFactory -> getPlains (); $skov = $prototypeFactory -> getForest ();

Ruby eksempel

Ruby kildekode modul prototype # "prototype" klasse prototype # Ejendom # egenskaben id er oprindeligt til stede for hvert objekt, så vi vil bruge egenskaben navn attr_reader :navn # konstruktør def initialisere navn @navn = navn slut ende ende # Opret en instans og klon den p1 = Prototype :: Prototype . nyt "mit navn" # Prototype-klasseobjektet oprettes på traditionel måde - ved metoden new p2 = p1 . clone # klonmetoden findes på hvert objekt som standard - det behøver ikke at være defineret sætter "p1.id = #{ p1 . objekt_id } , p2.id = #{ p2 . objekt_id } " # forskellige id'er vil blive udskrevet sætter "p1.navn = #{ p1 . navn } , p2.navn = #{ p2 . name } " # identiske navne vil blive udskrevet - "mit navn" # Vent på, at brugeren får

VB.NET eksempel

Kildetekst på VB.NET sprog Namespace Prototype Klasse MainApp Shared Sub Main () ' Opret to forekomster og klon hver Dim p1 As Prototype = New ConcretePrototype1 ( "I" ) Dim c1 As Prototype = p1 . Klon () konsol . WriteLine ( "Klon: ​​{0}" , c1 . Id ) Dim p2 As Prototype = New ConcretePrototype2 ( "II" ) Dim c2 As Prototype = p2 . Klon () konsol . WriteLine ( "Klon: ​​{0}" , c2 . Id ) Konsol . Læs () End Sub End Class "Prototype" MustInherit Class Prototype Private m_id As String ' Constructor Public Sub New ( ByVal id As String ) Me . m_id = id End Sub ' Public ReadOnly Property Id () As String Get Return m_id End Get End Property Offentlig MustOverride Funktion Klon ( ) Som Prototype Slutklasse ' "Betonprototype1" Klasse BetonPrototype1 Arver Prototype ' Constructor Public Sub New ( ByVal id As String ) MyBase . Ny ( id ) End Sub Offentlige tilsidesættelser Funktion Klon () Som prototype ' Ufuldstændig kopi Returner DirectCast ( Mig . MemberwiseClone ( ) , Prototype ) Slutfunktion Slutklasse ' "Betonprototype2" Klasse ConcretePrototype2 arver prototype ' Constructor Public Sub New ( ByVal id As String ) MyBase . Ny ( id ) End Sub Offentlige tilsidesættelser Funktion Klon () Som prototype ' Ufuldstændig kopi Returner DirectCast ( Mig . MemberwiseClone ( ) , Prototype ) Slutfunktion Slutningsklasse Slutnavneområde

Delphi eksempel

Kildetekst i Delphi program PrototypePattern ; {$APPTYPE KONSOL} bruger SysUtils ; type TPrototype = klasse offentlig funktion Klon : TPrototype ; virtuel ; abstrakt ; ende ; type TPrototypeType = klasse ( TPrototype ) privat FID : Heltal ; FInfo : String ; public property ID : Heltal læs FID skriv FID ; ejendom Info : Streng læs FIinfo skriv FIinfo ; funktion Klon : TPrototype ; tilsidesætte ; ende ; funktion TPrototypeType . Klon : T Prototype ; var vClone : ​​TPrototypeType ; start vClone := TPrototypeType . skabe ; vClone . ID := ID ; vClone . Info := Info ; Resultat := vClone ; ende ; procedure CloneAndShow ( Prototype : TPrototypeType ) ; var vClone : ​​TPrototypeType ; start vClone := Prototype . klon ; prøv Skriv ( vClone . ID ) ; Skriv ( vClone.Info ) ; _ _ endelig vClone . Gratis ; ende ; WriteLn ; ende ; var vConcretePrototype1 , vConcretePrototype2 : TPrototypeType ; start vConcretePrototype1 := TPrototypeType . skabe ; vConcretePrototype2 := TPrototypeType . skabe ; prøv vConcretePrototype1 . ID := 10 ; vConcretePrototype1 . Info := 'Prototype1!' ; vConcretePrototype2 . ID := 11 ; vConcretePrototype2 . Info := 'Prototype2!' ; CloneAndShow ( vConcretePrototype1 ) ; CloneAndShow ( vConcretePrototype2 ) ; endelig vConcretePrototype1 . Gratis ; vConcretePrototype2 . Gratis ; ende ; Læsln ; ende .

CoffeeScript-eksempel

CoffeeScript eksempel klasse PresidentPrototype - konstruktør: (@proto) -> klon: ​​-> kunde = ny præsident () customer.first = @proto . første kunde.sidste = @proto . sidste kunde.aka = @proto . a.k. en kunde klasse Præsident konstruktør: (@first, @last, @aka) -> sig : -> konsol . log "Hans navn er #{ @first } #{ @last } aka #{ @aka } ." run = -> proto = ny præsident ( "Jimmy" , "Wales" , "Jimbo" ) prototype = ny præsidentPrototype ( proto ) kunde = prototype . klone () kunde . sige () løb ()

Io eksempel

Io kildekode Foo := Objekt klon Foo smth := 2 Bar := Foo klon

Litteratur

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides . Teknikker til objektorienteret design. Designmønstre = Designmønstre: Elementer af genanvendelig objektorienteret software. - Sankt Petersborg. : "Peter" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (også ISBN 5-272-00355-1 )

Se også

Links