Prototyyppi (suunnittelumalli)

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 9. maaliskuuta 2016 tarkistetusta versiosta . tarkastukset vaativat 11 muokkausta .
Prototyyppi
prototyyppi
Tyyppi tuottaa
Kuvattu suunnittelukuvioissa Joo

Prototyyppi , ( eng.  Prototype )  - generoiva suunnittelukuvio .

Tapaaminen

Määrittää prototyyppiinstanssilla luotavien objektien tyypit ja luo uusia objekteja kopioimalla tämän prototyypin. Sen avulla voit päästä eroon toteutuksesta ja voit seurata "ohjelmoinnin rajapintojen kautta" -periaatetta. Hierarkian huipulla oleva rajapinta/abstrakti luokka on määritetty palautuvaksi tyypiksi, ja jälkeläisluokat voivat korvata perillisen, joka toteuttaa tämän tyypin siellä.

Yksinkertaisesti sanottuna tämä on malli, jossa objekti luodaan kloonaamalla toinen objekti sen sijaan, että se luodaan rakentajan avulla.

Sovellus

Mallia käytetään:

Käytä tätä suunnittelumallia, kun järjestelmä ei välitä siitä, miten tuotteet luodaan, pakataan ja esitetään siinä:

Esimerkkejä

Python-esimerkki

Lähdekoodi Pythonissa #!/usr/bin/env python # -*- koodaus: utf-8 -*- tuontikopio _ luokan prototyyppi : def __init__ ( itse ): itse . _objects = {} def register_object ( self , name , obj ): """Rekisteröi objekti""" self . _objektit [ nimi ] = objekti def unregister_object ( self , name ): """Peruuta objektin rekisteröinti""" del self . _objektit [ nimi ] def clone ( self , name , ** attr ): """Kloonaa rekisteröity objekti ja päivitä sisäinen attribuuttisanakirja""" obj = kopioi . syväkopio ( itse . _objektit . saada ( nimi )) obj . __sane__ . päivitä ( attr ) return obj luokka A : def __init__ ( itse ): itse . x = 3 itse . y = 8 itse . z = 15 itse . roskat = [ 38 , 11 , 19 ] def __str__ ( itse ): palauttaa ' {} {} {} {} ' . muoto ( itse . x , itse . y , itse . z , itse . roska ) def main (): a = A () prototyyppi = Prototyyppi () prototyyppi . register_object ( 'objekti' , a ) b = prototyyppi . klooni ( 'objekti' ) c = prototyyppi . klooni ( 'objekti' , x = 1 , y = 2 , roska = [ 88 , 1 ]) tulosta ([ str ( i ) for i in ( a , b , c )]) if __name__ == '__main__' : main ()
      1. TULOS ###
  1. ['3 8 15 [38, 11, 19]", "3 8 15 [38, 11, 19]", "1 2 15 [88, 1]"]

C++ esimerkki

Lähdeteksti C++:ssa luokan ateria { julkinen : virtuaalinen ~ ateria (); virtuaalinen tyhjä syö () = 0 ; virtuaalinen ateria * klooni () const = 0 ; //... }; luokan spagetti : julkinen ateria { julkinen : Spagetti ( const Spaghetti & ); tyhjä syö (); Spagetti * klooni () const { return new Spaghetti ( * this ); } //... };

Java-esimerkki

Java lähde /** * Prototyyppiluokka */ julkinen luokka Eväste toteuttaa Kloonattavissa { suojattu sisäpaino ; _ @Override public Evästeklooni ( ) heittää CloneNotSupportedException { Cookie copy = ( Cookie ) super . klooni (); //Tämän mallin todellisessa toteutuksessa voit nyt muuttaa viittauksia //kalleihin osien tuottamiseen prototyypin sisällä olevista kopioista. palautuskopio ; _ } } /** * Kloonattavat konkreettiset prototyypit */ julkinen luokka CoconutCookie laajentaa evästettä { } /** * Asiakasluokka */ julkinen luokka CookieMachine { yksityinen Evästeeväste ; _ // Olisi voinut olla yksityinen kloonattava eväste. public CookieMachine ( Cookie cookie ) { this . eväste = eväste _ } public Cookie makeCookie () heittää CloneNotSupportedException { return ( Cookie ) this . eväste . klooni (); } public static void main ( String args [ ] ) heittää CloneNotSupportedException { Cookie tempCookie = null ; Cookie prot = uusi CoconutCookie (); CookieMachine cm = uusi CookieMachine ( prot ); for ( int i = 0 ; i < 100 ; i ++ ) tempCookie = cm . makeCookie (); } }

Scala esimerkki

Scala lähdekoodi package.com _ pakettiobjektin prototyyppi { _ luokka Vohveli ( suojattu var - nimi : merkkijono , suojattu var ensisijainen Täyte : merkkijono , suojattu var erityinenTäyttö : Optio [ String ] = Ei mitään ) extends Kloonattavissa { ohita def- klooni (): Vohveli = { super . klooni (). asInstanceOf [ Vohveli ] } def output () : Yksikkö = { println ( s" vohvelin $ nimi ensisijaisella täytteellä $ ensisijainen täyttö " + ( if ( specialFilling != Ei mitään ) specialFilling . get else "" )) } } object PrototypeTest { def main ( args : Array [ String ]) : Yksikkö = { println ( "Tuloste:" ) val chocolateWaffle = uusi Vohveli ( "SuklaaWaffle" , "Suklaa" ) chocolateWaffle . tulos () suklaavohveli . klooni (). output () val coconutWaffle = uusi Vohveli ( "CoconutWaffle" , "Condensed milk" , Some ( "Coconut" ) )) coconutWaffle . lähtö () kookosvohveli . klooni (). lähtö () } } } . _ _ _ _

Esimerkki C#:ssa

Lähdeteksti C# käyttäen System ; nimitila Prototyyppi { class MainApp { static void Main () { // Luo kaksi esiintymää ja kloonaa jokainen prototyyppi prototyyppi1 = new ConcretePrototype1 ( "I" ); Prototyyppi kloonattuPrototyyppi1 = prototyyppi1 . klooni (); konsoli . WriteLine ( "Klooni: ​​{0}" , kloonattuPrototyyppi1 . Id ); Prototyyppi prototyyppi2 = uusi ConcretePrototype2 ( "II" ); Prototyyppi kloonattuPrototyyppi2 = prototyyppi2 . klooni (); konsoli . WriteLine ( "Kloonattu: {0}" , kloonattuPrototyyppi2 . Id ); } } // "Prototyyppi" public abstrakti luokka Prototyyppi { // Rakentaja public Prototype ( string id ) { this . id = id ; konsoli . Write ( "Peruskonstruktori kutsutaan." ); } // Omaisuuden julkinen merkkijono Id { get ; yksityinen sarja ; } public virtual Prototype Clone () { // Matala kopio palauttaa ( Prototype ) this . MemberwiseClone (); } } // "ConcretePrototype1" public class ConcretePrototype1 : Prototype { // Rakentaja public ConcretePrototype1 ( string id ) : base ( id ) { } } // "ConcretePrototype2" public class ConcretePrototype2 : Prototype { // Rakentaja public ConcretePrototype2 ( string id ) : base ( id ) { } } }

PHP-esimerkki

PHP lähdekoodi

<?php /** * Prototyyppien kelvollisten luokkien hierarkia */ abstrakti luokka Maasto {} abstrakti luokka Meri ulottuu Maasto {} luokka MaaSea ulottuu Meri { } luokka MarsSea ulottuu Meri {} luokka VenusSea ulottuu meri {} abstrakti luokka tasangot tasangot { } luokka EarthPlains tasangot { } luokka MarsPlains tasangot { } luokka VenusPlains tasangot { } abstrakti luokka Metsä laajentaa Maastoa {} luokka EarthForest laajentaa metsää {} luokka MarsForest laajentaa metsää {} luokka VenusForest laajentaa metsää {} /** * Prototyypin tehdaslogiikan määrittely */ luokka TerrainFactory { yksityinen $meri ; yksityinen $metsä ; yksityinen $plains ; julkinen toiminto __konstrukti ( Meri $meri , Tasangot $tasangot , Metsä $metsä ) { $this -> meri = $meri ; $this -> plains = $plains ; $this -> metsä = $metsä ; } function getSea ( ) { paluu klooni $this -> meri ; } function getPlains ( ) { paluu klooni $this -> plains ; } function getForest ( ) { return klooni $this -> metsä ; } } /** * Luo tehdas annetuilla prototyyppiparametreilla */ $prototypeFactory = new TerrainFactory ( uusi EarthSea (), uusi MarsPlains (), uusi VenusForest () ); /** * Luo annetut objektit kloonaamalla */ $sea = $prototypeFactory -> getSea (); $plains = $prototypeFactory -> getPlains (); $metsä = $prototypeFactory -> getForest ();

Rubiiniesimerkki

Rubyn lähdekoodi moduulin prototyyppi # "prototyyppi" luokan prototyyppi # Ominaisuus # id-ominaisuus on alun perin jokaisessa objektissa, joten käytämme ominaisuutta nimi attr_reader :nimi #rakentaja def alusta nimi @nimi = nimen loppu loppu loppu # Luo ilmentymä ja kloonaa se p1 = Prototyyppi :: Prototyyppi . uusi "nimeni" # Prototype-luokan objekti luodaan perinteisellä tavalla - menetelmällä new p2 = p1 . clone # kloonausmenetelmä on oletuksena jokaisessa objektissa - sitä ei tarvitse määrittää laittaa "p1.id = #{ p1 . objektin_tunnus } , p2.id = #{ p2 . objektin_tunnus } " # erilaista tunnusta tulostetaan laittaa "p1.name = #{ p1 . name } , p2.name = #{ p2 . nimi } " # identtistä nimeä tulostetaan - "nimeni" # Odota, että käyttäjä saa

VB.NET esimerkki

Lähdeteksti VB.NET-kielellä Nimitilan prototyyppiluokka MainApp Shared Sub Main () ' Luo kaksi esiintymää ja kloonaa kumpikin Himmeä p1 Prototyyppinä = Uusi ConcretePrototype1 ( " I " ) Dim c1 Prototypena = p1 . Kloonaa () -konsoli . WriteLine ( "Klooni: ​​{0}" , c1 . Id ) Dim p2 As Prototype = Uusi ConcretePrototype2 ( "II" ) Dim c2 As Prototype = p2 . Kloonaa () -konsoli . WriteLine ( "Klooni: ​​{0}" , c2 . Id ) konsoli . Lue () Lopeta Sub End Class "Prototyyppi" MustInherit Class Prototype Yksityinen m_id merkkijonona _ ' Constructor Public Sub New ( ByVal id As String ) Me . m_id = id End Sub ' Julkinen vain luku -ominaisuuden tunnus ( ) merkkijonona Hanki Palautus m_id Loppu Hanki loppuomaisuus Julkinen MustOverride Function Clone ( ) Prototyypin loppuluokkana _ "ConcretePrototype1" Luokka ConcretePrototype1 Peri Prototype ' Constructor Public Sub New ( ByVal id As String ) MyBase . Uusi ( id ) End Sub Julkinen ohittaa funktion Klooni () Prototyyppinä ' Epätäydellinen kopio Palauta DirectCast ( Me . MemberwiseClone ( ) , Prototyyppi ) Loppufunktion loppuluokka "ConcretePrototype2" Luokka ConcretePrototype2 perii prototyypin Constructor Public Sub New ( ByVal id As String ) MyBase . Uusi ( id ) End Sub Julkinen ohittaa funktion Klooni () Prototyyppinä ' Epätäydellinen kopio Palauta DirectCast ( Me . MemberwiseClone ( ) , Prototyyppi ) Loppufunktio End Class End Namespace

Delphi esimerkki

Lähdeteksti Delphissä ohjelma PrototypePattern ; {$APPTYPE CONSOLE} käyttää SysUtilsia ; tyyppi TPrototyyppi = luokka julkinen toiminto Klooni : TPrototyyppi ; virtuaalinen ; abstrakti ; loppu ; tyyppi TPrototypeType = luokka ( TPototyyppi ) yksityinen FID : Kokonaisluku ; Finfo : String ; julkinen omaisuustunnus : Kokonaisluku lue FID kirjoittaa FID ; _ ominaisuus Info : Merkkijono lukea FIinfo kirjoittaa FIinfo ; toiminto Klooni : TPrototyyppi ; ohittaa ; loppu ; toiminto TPrototypeType . Klooni : T Prototyyppi ; var vClone : ​​TPrototypeType ; begin vClone := TPrototypeType . luoda ; vClone . ID := ID ; vClone . Info := Info ; Tulos := vClone ; loppu ; menettely CloneAndShow ( Prototyyppi : TPrototypeType ) ; var vClone : ​​TPrototypeType ; begin vClone := Prototyyppi . klooni ; yritä kirjoittaa ( vClone . ID ) ; Kirjoita ( vClone.Info ) ; _ _ lopulta vClone . Ilmainen ; loppu ; WriteLn ; loppu ; var vConcretePrototype1 , vConcretePrototype2 : TPrototypeType ; begin vConcretePrototype1 := TPrototypeType . luoda ; vConcretePrototype2 := TPrototyyppityyppi . luoda ; kokeile vConcretePrototype1 . ID := 10 ; vConcretePrototype1 . Info := 'Prototyyppi1!' ; vConcretePrototype2 . ID := 11 ; vConcretePrototype2 . Info := 'Prototyyppi2!' ; CloneAndShow ( vConcretePrototype1 ) ; CloneAndShow ( vConcretePrototype2 ) ; lopuksi vConcretePrototype1 . Ilmainen ; vConcretePrototype2 . Ilmainen ; loppu ; Readln ; loppua .

CoffeeScript-esimerkki

CoffeeScript esimerkki luokan PresidenttiPrototyypin rakentaja: (@proto) -> klooni: ​​-> asiakas = uusi presidentti () asiakas.first = @proto . ensimmäinen asiakas.viimeinen = @proto . viimeinen asiakas.aka = @proto . a.k.a asiakas luokan Presidentti rakentaja: (@first, @last, @aka) -> sano: -> konsoli . log "Hänen nimensä on #{ @first } #{ @last } eli #{ @aka } ." run = -> proto = uusi presidentti ( " Jimmy " , " Wales " , " Jimbo " ) prototyyppi = uusi presidenttiPrototyyppi ( proto ) asiakas = prototyyppi . klooni () asiakas . sano () juosta ()

Io esimerkki

Io lähdekoodi Foo := Objektiklooni Foo smth := 2 bar : = Foo klooni

Kirjallisuus

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides . Olio-suunnittelun tekniikat. Suunnittelumallit = Suunnittelumallit: Uudelleenkäytettävän olio-ohjelmiston elementit. - Pietari. : "Peter" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (myös ISBN 5-272-00355-1 )

Katso myös

Linkit