Prototip (model de design)

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită la 9 martie 2016; verificările necesită 11 modificări .
Prototip
prototip
Tip de generatoare
Descris în Design Patterns da

Prototip , ( ing.  Prototype )  - model de proiectare generator .

Numire

Specifică tipurile de obiecte care vor fi create folosind o instanță de prototip și creează obiecte noi prin copierea acestui prototip. Vă permite să vă îndepărtați de implementare și vă permite să urmați principiul „programarii prin interfețe”. O interfață/clasă abstractă din vârful ierarhiei este specificată ca tip de revenire, iar clasele descendente pot înlocui un moștenitor care implementează acest tip acolo.

Pur și simplu, acesta este modelul de a crea un obiect prin clonarea unui alt obiect în loc să-l creeze printr-un constructor.

Aplicație

Modelul este folosit pentru:

Utilizați acest model de design atunci când sistemului nu îi pasă cum sunt create, ambalate și prezentate produsele în el:

Exemple

Exemplu Python

Cod sursă în Python #!/usr/bin/env python # -*- codificare: utf-8 -*- importa copie clasa prototip : def __init__ ( self ): sine . _obiecte = {} def register_object ( self , name , obj ): """Înregistrați un obiect""" self . _obiecte [ nume ] = obj def unregister_object ( self , name ): """Anulați înregistrarea unui obiect""" del self . _obiecte [ nume ] def clone ( self , name , ** attr ): """Clonează un obiect înregistrat și actualizează dicționarul de atribute interioare""" obj = copy . deepcopy ( self . _objects . get ( nume )) obj . __dict__ . update ( attr ) return obj clasa A : def __init__ ( self ): self . x = 3 auto . y = 8 sine . z = 15 auto . gunoi = [ 38 , 11 , 19 ] def __str__ ( self ): returnează ' {} {} {} {} ' . format ( self . x , self . y , self . z , self . garbage ) def main (): a = A () prototype = Prototype () prototip . register_object ( 'objecta' , a ) b = prototip . clonă ( 'objecta' ) c = prototip . clone ( 'objecta' , x = 1 , y = 2 , garbage = [ 88 , 1 ]) print ([ str ( i ) pentru i in ( a , b , c )]) if __name__ == '__main__' : main ()
      1. IEȘIRE ###
  1. ['3 8 15 [38, 11, 19]', '3 8 15 [38, 11, 19]', '1 2 15 [88, 1]']

Exemplu C++

Text sursă în C++ masă de clasă { public : virtual ~ masa (); virtual void eat () = 0 ; virtual Meal * clone () const = 0 ; //... }; clasă Spaghete : masă publică { public : Spaghetti ( const Spaghetti & ); void eat (); Spaghetti * clone () const { return new Spaghetti ( * this ); } //... };

Exemplu Java

Sursa Java /** * Clasa prototip */ clasă publică Cookie implementează Cloneable { greutate int protejată ; @Override public Cookie clone () throws CloneNotSupportedException { Cookie copy = ( Cookie ) super . clona (); //Într-o implementare reală a acestui model, s-ar putea acum să schimbați referințele la //producția de piese costisitoare din copiile care sunt deținute în interiorul prototipului. returnează copie ; } } /** * Prototipuri concrete de clonat */ public class CoconutCookie extinde Cookie { } /** * Clasa client */ clasă publică CookieMachine { cookie cookie privat ; // Ar fi putut fi un cookie privat clonabil. public CookieMachine ( cookie cookie ) { this . cookie = cookie _ } public Cookie makeCookie () aruncă CloneNotSupportedException { return ( Cookie ) this . cookie . clona (); } public static void main ( String args [] ) aruncă CloneNotSupportedException { Cookie tempCookie = null ; Cookie prot = nou CoconutCookie (); CookieMachine cm = nou CookieMachine ( prot ); pentru ( int i = 0 ; i < 100 ; i ++ ) tempCookie = cm . faceCookie (); } }

Exemplu Scala

Codul sursă Scala pachet.com _ prototip obiect pachet { class Waffle ( nume var protejat : String , var protejat primaryFilling : String , var protejat specialFilling : Opțiune [ String ] = Nici unul ) se extinde Cloneable { override def clone (): Waffle = { super . clona (). asInstanceOf [ Waffle ] } def output () : Unit = { println ( s"Waffle $ nume cu umplutura primară $ primaryFilling " + ( if ( specialFilling != None ) specialFilling . get else "" )) } } obiect PrototypeTest { def main ( args : Array [ String ]) : Unit = { println ( "Ieșire:" ) val chocolateWaffle = new Waffle ( "ChocolateWaffle" , "Chocolate" ) chocolateWaffle . ieșire () chocolateWaffle . clona (). output () val coconutWaffle = new Waffle ( „CoconutWaffle” , „Lapte condensat” , Some ( „Cocos” ) )) coconutWaffle . ieșire () cocosWaffle . clona (). ieșire () } } } // Ieșire: // Waffle ChocolateVafe cu umplutură primară Ciocolată // Waffle ChocolateVafe cu umplutură primară Ciocolată // Waffle CocosVaffle cu umplutură primară Lapte condensatNucă de cocos // Waffle Cocos Waffle cu umplutură primară Lapte condensatNucă de cocos

Exemplu în C#

Text sursă în C# folosind System ; namespace Prototype { class MainApp { static void Main () { // Creați două instanțe și clonați fiecare Prototype prototype1 = new ConcretePrototype1 ( "I" ); Prototype clonedPrototype1 = prototip1 . clona (); Consola . WriteLine ( "Clone: ​​​​{0}" , clonedPrototype1 . Id ); Prototip prototip2 = nou ConcretePrototype2 ( "II" ); Prototype clonedPrototype2 = prototype2 . clona (); Consola . WriteLine ( "Clonat: {0}" , clonedPrototype2 . Id ); } } // „Prototip” clasă abstractă publică Prototip { // Constructor public Prototype ( string id ) { this . id = id ; Consola . Write ( "Constructorul de bază este numit." ); } // Proprietatea public șir Id { get ; set privat ; } public virtual Prototype Clone () { // Copie superficială returnează ( Prototip ) this . MemberwiseClone (); } } // Clasa publică „ConcretePrototype1” ConcretePrototype1 : Prototype { // Constructor public ConcretePrototype1 ( string id ) : bază ( id ) { } } // Clasa publică "ConcretePrototype2" ConcretePrototype2 : Prototype { // Constructor public ConcretePrototype2 ( șir de caractere id ) : bază ( id ) { } } }

Exemplu PHP

Cod sursă PHP

<?php /** * Ierarhia claselor valide pentru prototipare */ abstract class Terrain {} clasa abstractă Marea se extinde Teren {} clasa PământMarea se extinde Marea {} clasa MarteMarea se extinde Marea {} clasa VenusMarea se extinde Marea {} clasa abstractă Câmpii se extinde Teren {} clasă Pământ Câmpie se extinde Câmpii {} clasă MarsPlains se extinde Câmpii {} clasa Venus Câmpie se extinde Câmpii {} clasa abstractă Forest se extinde Teren {} clasa EarthForest se extinde Forest {} class MarsForest se extinde Forest {} clasa VenusForest se extinde Forest {} /** * Definirea logicii fabricii prototip */ class TerrainFactory { private $sea ; privat $forest ; private $plains ; public function __construct ( Marea $mare , Campii $campii , Padure $padure ) { $aceasta -> mare = $mare ; $acest -> câmpii = $câmpii ; $acest -> pădure = $pădure ; } function getSea ( ) { return clone $this -> sea ; } function getPlains ( ) { return clone $this -> plains ; } function getForest ( ) { return clone $this -> forest ; } } /** * Creați o fabrică cu parametrii prototipului dați */ $prototypeFactory = new TerrainFactory ( new EarthSea (), new MarsPlains (), new VenusForest () ); /** * Creați obiectele date prin clonarea */ $sea = $prototypeFactory -> getSea (); $plains = $prototypeFactory -> getPlains (); $forest = $prototypeFactory -> getForest ();

Exemplu Ruby

Cod sursă Ruby modul Prototip # „prototip” clasa Prototip # Proprietatea # proprietatea id este prezentă inițial pentru fiecare obiect, așa că vom folosi proprietatea name attr_reader :nume # constructor def initialize name @name = name end sfârşitul sfârşitului # Creați o instanță și clonați-o p1 = Prototype :: Prototype . nou „numele meu” # obiectul clasei Prototype este creat în mod tradițional - prin metoda new p2 = p1 . clone # metoda clonării există în mod implicit pe fiecare obiect - nu trebuie să fie definită pune "p1.id = #{ p1 . object_id } , p2.id = #{ p2 . object_id } " # diferite ID-uri vor fi tipărite pune "p1.name = #{ p1 . nume } , p2.name = #{ p2 . name } " # nume identice vor fi tipărite - "numele meu" # Așteptați ca utilizatorul să primească

Exemplu VB.NET

Text sursă în limba VB.NET Namespace Prototype Class MainApp Shared Sub Main () ' Creați două instanțe și clonați fiecare Dim p1 As Prototype = New ConcretePrototype1 ( " I " ) Dim c1 As Prototype = p1 . Clonează () Consolă . WriteLine ( "Clone: ​​​​{0}" , c1 . Id ) Dim p2 As Prototype = New ConcretePrototype2 ( "II" ) Dim c2 As Prototype = p2 . Clonează () Consolă . WriteLine ( "Clone: ​​​​{0}" , c2 . Id ) Consola . Citiți () End Sub End Class "Prototip" MustInherit Class Prototype Private m_id As String ' Constructor Public Sub New ( ByVal id As String ) Eu . m_id = id End Sub ' Public ReadOnly Property Id () As String Get Return m_id End Get End Property Funcția publică MustOverride Clone () ca prototip de clasă finală ' "ConcretePrototype1" Clasa ConcretePrototype1 Moștenește Prototipul ' Constructor Public Sub New ( ByVal id As String ) MyBase . Nou ( id ) End Sub Public Overscrie Funcția Clonează () Ca prototip ' Copie incompletă Returnează DirectCast ( Me . MemberwiseClone (), Prototip ) End Function End Class "ConcretePrototype2" Clasa ConcretePrototype2 moștenește Prototype ' Constructor Public Sub New ( ByVal id As String ) MyBase . Nou ( id ) End Sub Public Overscrie Funcția Clonează () Ca prototip ' Copie incompletă Returnează DirectCast ( Eu . MemberwiseClone (), Prototip ) Sfârșit funcție Sfârșit clasă Sfârșit spațiu de nume

Exemplu Delphi

Text sursă în Delphi programul PrototypePattern ; {$APPTYPE CONSOLE} folosește SysUtils ; tip TPrototype = clasă funcție publică Clone : ​​TPrototype ; virtual ; abstract ; sfârşitul ; tip TPrototypeType = clasa ( TPrototype ) privat FID : Integer ; FInfo : String ; ID proprietate publică : Întregul citire FID scriere FID ; Informații proprietăți : String citiți FInfo scrieți FInfo ; funcția Clonare : TPrototype ; suprascrie ; sfârşitul ; funcția TPrototypeType . Clona : T Prototype ; var vClone : ​​TPrototypeType ; începe vClone := TPrototypeType . a crea ; vClone . ID := ID ; vClone . Info := Info ; Rezultat := vClone ; sfârşitul ; procedura CloneAndShow ( Prototip : TPrototypeType ) ; var vClone : ​​TPrototypeType ; începe vClone := Prototip . clonare ; încercați să scrieți ( vClone . ID ) ; Scrie ( vClone.Info ) ; _ _ în sfârșit vClone . Gratuit ; sfârşitul ; WriteLn ; sfârşitul ; var vConcretePrototype1 , vConcretePrototype2 : TPrototypeType ; începe vConcretePrototype1 := TPrototypeType . a crea ; vConcretePrototype2 := TPrototypeType . a crea ; încercați vConcretePrototype1 . ID := 10 ; vConcretePrototype1 . Info := 'Prototip1!' ; vConcretePrototype2 . ID := 11 ; vConcretePrototype2 . Info := 'Prototip2!' ; CloneAndShow ( vConcretePrototype1 ) ; CloneAndShow ( vConcretePrototype2 ) ; în cele din urmă vConcretePrototype1 . Gratuit ; vConcretePrototype2 . Gratuit ; sfârşitul ; Readln ; sfârşitul .

Exemplu CoffeeScript

Exemplu CoffeeScript clasa PresidentPrototype constructor: (@proto) -> clonă: ​​-> client = nou Președinte () client.first = @proto . primul client.last = @proto . ultimul client.aka = @proto . a.k.a client constructor de clasă Președinte : (@first, @last, @aka) -> spune: -> console . log „Numele lui este #{ @first } #{ @last } alias #{ @aka } ." rula = -> proto = nou Președinte ( „Jimmy” , „Wales” , „Jimbo” ) prototip = nou PresidentPrototype ( proto ) client = prototip . clona () client . spune () alerga ()

Io exemplu

Io cod sursă Foo := Clona obiect Foo smth := 2 Bar := Clona Foo

Literatură

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides . Tehnici de proiectare orientată pe obiecte. Design Patterns = Design Patterns: Elements of Reusable Object-Oriented Software. - Sankt Petersburg. : „Petru” , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (și ISBN 5-272-00355-1 )

Vezi și

Link -uri