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 , ( 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:
- pentru a evita eforturile suplimentare de a crea un obiect într-un mod standard (adică folosirea unui constructor, deoarece în acest caz vor fi chemați și constructorii întregii ierarhii a strămoșilor obiectului), când acest lucru este prohibitiv de costisitor pentru aplicație.
- evitați moștenirea creatorului de obiect în aplicația client, așa cum face modelul abstract din fabrică .
Utilizați acest model de design atunci când sistemului nu îi pasă cum sunt create, ambalate și prezentate produsele în el:
- clasele instanțiate sunt determinate în timpul rulării, de exemplu prin încărcare dinamică;
- evita construirea de ierarhii de clasă sau fabrici paralele cu ierarhia de clasă de produse;
- Instanțele de clasă pot fi într-una din mai multe stări diferite. Poate fi mai convenabil să setați numărul adecvat de prototipuri și să le clonați, mai degrabă decât să instanțiați manual clasa în starea corespunzătoare de fiecare dată.
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 ()
- IEȘIRE ###
- ['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