Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

README.md

title Prototype
shortTitle Prototype
category Creational
language es
tag
Gang Of Four
Instantiation

Propósito

Especificar los tipos de objetos a crear utilizando una instancia prototípica, y crear nuevos objetos copiando este prototipo

Explicación

Primero, debe notarse que el patrón Prototype no se utiliza para obtener beneficios de rendimiento. Solo se utiliza para crear nuevos objetos a partir de instancias prototipo.

Ejemplo del mundo real

¿Recuerdas a Dolly? ¡La oveja que fue clonada! No entremos en detalles, pero el punto clave aquí es que todo se trata de clonación.

En palabras simples

Crea un objeto basado en un objeto existente a través de la clonación.

Wikipedia dice

El patrón de prototipo es un patrón de diseño de creación en el desarrollo de software. Se utiliza cuando el tipo de objetos a crear está determinado por una instancia prototípica, que se clona para producir nuevos objetos.

En resumen, te permite crear una copia de un objeto existente y modificarla según tus necesidades, en lugar de pasar por el problema de crear un objeto desde cero y configurarlo.

Ejemplo Programático

En Java, se recomienda implementar el patrón prototipo de la siguiente manera. En primer lugar, cree una interfaz con un método para clonar objetos. En este ejemplo, la interfaz Prototype logra esto con su método copy.

public abstract class Prototype<T> implements Cloneable {
    @SneakyThrows
    public T copy() {
        return (T) super.clone();
    }
}

Nuestro ejemplo contiene una jerarquía de diferentes criaturas. Por ejemplo, veamos las clases Beast y OrcBeast.

@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
public abstract class Beast extends Prototype<Beast> {

  public Beast(Beast source) {
  }

}

@EqualsAndHashCode(callSuper = false)
@RequiredArgsConstructor
public class OrcBeast extends Beast {

  private final String weapon;

  public OrcBeast(OrcBeast orcBeast) {
    super(orcBeast);
    this.weapon = orcBeast.weapon;
  }

  @Override
  public String toString() {
    return "Orcish wolf attacks with " + weapon;
  }

}

No queremos entrar en demasiados detalles, pero el ejemplo completo contiene también las clases base Mage y Warlord y hay implementaciones especializadas para los elfos además de para los orcos.

Para aprovechar al máximo el patrón prototipo, creamos las clases HeroFactory y HeroFactoryImpl para producir diferentes tipos de criaturas a partir de prototipos.

public interface HeroFactory {
  
  Mage createMage();
  Warlord createWarlord();
  Beast createBeast();
}

@RequiredArgsConstructor
public class HeroFactoryImpl implements HeroFactory {

  private final Mage mage;
  private final Warlord warlord;
  private final Beast beast;

  public Mage createMage() {
    return mage.copy();
  }

  public Warlord createWarlord() {
    return warlord.copy();
  }

  public Beast createBeast() {
    return beast.copy();
  }
}

Ahora, somos capaces de mostrar el patrón prototipo completo en acción produciendo nuevas criaturas clonando instancias existentes.

    var factory = new HeroFactoryImpl(
        new ElfMage("cooking"),
        new ElfWarlord("cleaning"),
        new ElfBeast("protecting")
    );
    var mage = factory.createMage();
    var warlord = factory.createWarlord();
    var beast = factory.createBeast();
    LOGGER.info(mage.toString());
    LOGGER.info(warlord.toString());
    LOGGER.info(beast.toString());

    factory = new HeroFactoryImpl(
        new OrcMage("axe"),
        new OrcWarlord("sword"),
        new OrcBeast("laser")
    );
    mage = factory.createMage();
    warlord = factory.createWarlord();
    beast = factory.createBeast();
    LOGGER.info(mage.toString());
    LOGGER.info(warlord.toString());
    LOGGER.info(beast.toString());

Esta es la salida de la consola al ejecutar el ejemplo.

Elven mage helps in cooking
Elven warlord helps in cleaning
Elven eagle helps in protecting
Orcish mage attacks with axe
Orcish warlord attacks with sword
Orcish wolf attacks with laser

Diagrama de Clases

alt text

Aplicabilidad

Utilice el patrón Prototipo cuando un sistema deba ser independiente de cómo se crean, componen, representan sus productos y

  • Cuando las clases a instanciar se especifican en tiempo de ejecución, por ejemplo, mediante carga dinámica.
  • Para evitar construir una jerarquía de clases de fábricas paralela a la jerarquía de clases de productos.
  • Cuando las instancias de una clase solo pueden tener una de unas pocas combinaciones diferentes de estado. Puede ser más conveniente instalar un número correspondiente de prototipos y clonarlos en lugar de instanciar la clase manualmente, cada vez con el estado apropiado.
  • Cuando la creación de objetos es costosa en comparación con la clonación.

Usos conocidos

Créditos