PROTOTYPE DESIGN PATTERN

Il pattern Prototipo permette di creare nuovi oggetti clonando un oggetto iniziale, detto appunto prototipo. A differenza di altri pattern come Abstract factory permette di specificare nuovi oggetti a run-time, utilizzando un gestore di prototipi (prototype manager) per salvare e reperire dinamicamente le istanze degli oggetti desiderati.

Il Prototipo è uno dei design pattern fondamentali definiti dalla cosiddetta Gang of Four

prototype

DIAGRAMMA UML PROTOTYPE

Prototype

 

IMPLEMENTAZIONE PROTOTYPE

In primo luogo creiamo una classe astratta Figura e delle classi concrete che la implementano. La classe FiguraCache memorizza gli oggetti in una HashTable e ritornerà i cloni quando richiesto. Infine la classe Main utilizzerà FiguraCache per recuperare gli oggetti.

Step 1: Creare la classe astratta che implementa l’interfaccia Cloneable

public abstract class Figura implements Cloneable {

    private String id;
    protected String tipo;

    abstract void disegna();

    public String getTipo(){
        return tipo;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

Step 2: Creare le classi concrete che estendono Figura

Rettangolo.java

public class Rettangolo extends Figura {

    public Rettangolo(){
        tipo = "RETTANGOLO";
        disegna();
    }

    @Override
    public void disegna() {
        System.out.println("[RETTANGOLO] : disegna()");
    }
}

Quadrato.java

public class Quadrato extends Figura {

    public Quadrato(){
        tipo = "QUADRATO";
        disegna();
    }

    @Override
    public void disegna() {
        System.out.println("[QUADRATO] : disegna()");
    }
}

Cerchio.java

public class Cerchio extends Figura {

    public Cerchio(){
        tipo = "CERCHIO";
        disegna();
    }

    @Override
    public void disegna() {
        System.out.println("[CERCHIO] : disegna()");
    }
}

Step 3: Creare la classe per recuperare le classi concrete dal Database e salvarle nella HashTable (Prototype)

import java.util.Hashtable;

public class FiguraCache {

    private static Hashtable<String, Figura> figuraMap  = new Hashtable<String, Figura>();

    public static Figura getFigura(String figuraId) {
        Figura figuraShape = figuraMap.get(figuraId);
        return (Figura) figuraShape.clone();
    }

    // Per ogni figura inserisco nel "database"
    // figuraMap.put(figuraKey, figura);

    public static void caricaCache() {
        Cerchio cerchio = new Cerchio();
        cerchio.setId("1");
        figuraMap.put(cerchio.getId(),cerchio);

        Quadrato quadrato = new Quadrato();
        quadrato.setId("2");
        figuraMap.put(quadrato.getId(),quadrato);

        Rettangolo rettangolo = new Rettangolo();
        rettangolo.setId("3");
        figuraMap.put(rettangolo.getId(),rettangolo);
    }
}

Step 4: La classe Main utilizza la classe FiguraCache per recuperare la copia degli oggetti

public class Main {
    public static void main(String[] args) {
        FiguraCache.caricaCache();

        Figura figuraClone1 = (Figura) FiguraCache.getFigura("1");
        System.out.println("FIGURA: "+figuraClone1.getTipo());

        Figura figuraClone2 = (Figura) FiguraCache.getFigura("2");
        System.out.println("FIGURA: "+figuraClone2.getTipo());

        Figura figuraClone3 = (Figura) FiguraCache.getFigura("3");
        System.out.println("FIGURA: "+figuraClone3.getTipo());
    }
}

Step 5: Output

[CERCHIO] : disegna()
[QUADRATO] : disegna()
[RETTANGOLO] : disegna()
FIGURA: CERCHIO
FIGURA: QUADRATO
FIGURA: RETTANGOLO

 

LINK UTILI