El Prototype (Prototipus) és un patró de disseny del Software.Té com a finalitat crear nous objectes duplicant-los, clonant una instància creada prèviament.

Diagrama de classes modifica

 

Motivació modifica

Aquest patró és motiu on en certs escenaris cal abstreure la lògica que decideix quins tipus d'objectes utilitzar a una aplicació, de lògia que després usaran aquests objectes en la seva execució. Els motius d'aquesta separació poden ser varis, per exemples, pot ser que l'aplicació hagi de basar-se en alguna configuració, o paràmetre en el temps d'execució per decidir quins tipus d'objecte ha de crear

Solució modifica

Aquest patró proposa la creació de diferents variants de l'objecte que la nostra aplicació necessiti, en el moment i el context adequat. Tota la lògica necessària per a la decisió sobre el tipus s'objectes que usarà l'aplicació en la seva execució s'hauria de trobar aquí.

Després, el codi que utilitzen aquests objectes demanaran una còpia de l'objecte que necessiti. En aquest context, una còpia significa una altra instància de l'objecte. L'únic requisit que ha de complir aquest objecte és subministrar la prestació de clonar-se. Cada un dels objectes prototip ha d'implementar el mètode Clone().

Implementació modifica

Aquesta és una implementació en C.Sharp de DotNet:

using System;
// "Prototype"
abstract class Prototype {

	private string _id;

	public Prototype(string id) {
		_id = id;
	}

	public string ID {
		get{ return _id; }
	}

	abstract public Prototype Clone();
}

class ClsConcreta1 : Prototype {
	public ClsConcreta1 (string id) : base (id) {}

	override public Prototype Clone() {
		// Shallow copy
		return (Prototype)this.MemberwiseClone();
	}
}

class Prototype[[Client {
	
---- '''ClsConcreta1 y luego la clono
		ClsConcreta1 p1 = new ClsConcreta'''
1 ("Clone-I");
		ClsConcreta1 c1 = (ClsConcreta1) p1.Clone();
		Console.WriteLine("Clonació: {0}", c1.ID);		
	}
}

Aquesta és una altra implementació diferent en Java:

// Els productes han d'implementar aquesta interficie
public interface Producto extends Cloneable {
 Object clone();
 // Aquí hi van totes les operacions comunes als productes que genera la factoria
}

// Un exemple bàsic de producte
public class UnProducto implements Producto {
 private int atributo;

 UnProducto(int atributo) {
 this.atributo = atributo;
 }

 public Object clone() {
 return new UnProducto(this.atributo);
 }

 public String toString() {
 return ((Integer)atributo).toString();
 }
}

// La classe encarregada de crear objectes a partir del prototip
public class FactoriaPrototipo {
 private HashMap mapaObjetos;
 private String nombrePorDefecto;

 public FactoriaPrototipo() {
 mapaObjetos = new HashMap();
 // S'inclouen al mapa tots els productes prototip
 mapaObjetos.put("producto 1", new UnProducto(1));
 }

 public Object create() {
 return create(nombrePorDefecto);
 }

 public Object create(String nombre) {
 nombrePorDefecto = nombre;
 UnProducto objeto = (UnProducto)mapaObjetos.get(nombre);
 return objeto != null ? objeto.clone() : null;
 }
}

public class PruebaFactoria {
 static public void main(String[] args) {
 FactoriaPrototipo factoria = new FactoriaPrototipo();
 Producto producto = (Producto) factoria.create("producto 1");
 System.out.println ("Aquest és l'objecte creat: " + producto);
 }
}