Mètode Template

De Viquipèdia
(S'ha redirigit des de: Template method)
Dreceres ràpides: navegació, cerca

A dins del marc de la programació orientada a objectes, el patró mètode Template (mètode plantilla o model) és un patró per solucionar problemes comuns de programari. El patró de disseny Template Method és un patró de comportament, aquest patró ens permet definir una estructura algorítmica a la superclasse, delegant la implementació d'alguns mètodes a les subclasses. És un patró que utilitza el principi de Hollywood: Don't call us, we'll call you! a més ens facilita la utilització de hooks.

El mètode Template és un patró de comportament que serveix per definir l'esquelet d'un algorisme, delegant a les seves subclasses alguns dels passos d'aquest algorisme. El mètode Template és utilitzat quan moltes classes han d'implementar un mateix comportament que només varia en algunes parts, també ens trobem amb la implementació de mètodes de ganxo (hooks), petits salts en el flux del programa que ens permeten realitzar consultes a les classes concretes, el patró template també utilitza el principi de Hollywood (o principi d'inversió): Don't call us, we'll call you.

Propòsit[modifica | modifica el codi]

Permetre que certs passos d'un algorisme definit en una operació d'una superclasse, siguin re-definits en les subclasses sense necessitat d'haver de sobreescriure l'operació sencera.

Aplicabilitat[modifica | modifica el codi]

La utilització del patró  Mètode plantilla és adequada en els següents casos:

  • Quan tenim un algorisme amb diversos passos que no canvien, tal que canvien per les subclasses.
  • Per evitar la replicació de codi amb la generalització del comportament comú de diverses subclasses en una única superclasse.
  • Per controlar les extensions de les subclasses. El mètode Template utilitza mètodes especials (mètodes de ganxo o hooks) en alguns punts, sent els únics punts que poden ser redefinits i per tant els únics punts on és possible l'extensió.

Estructura[modifica | modifica el codi]

Es mostra a continuació l'estructura que utilitza el patró Template:

TemplateEstructura.jpeg

Participants[modifica | modifica el codi]

Classe Abstracta[modifica | modifica el codi]

Proporciona la definició d'una sèrie d'operacions primitives (normalment abstractes) que implementen els passos d'un algorisme i que seran definits en les subclasses. S'encarrega també de la implementació d'un mètode en el que s'invocaran entre altres les operacions primitives. Aquest mètode actua com plantilla, per això el nom del patró, definint la seqüència d'operacions d'un algorisme.

Classe Concreta[modifica | modifica el codi]

Implementa les operacions primitives definides en la classe abstracta de la qual hereta, quedant determinat el comportament específic de l'algorisme definit en el mètode plantilla, per cada subclasse.

Col·laboracions[modifica | modifica el codi]

Les classes concretes es basen en la classe abstracta per implementar la part invariant de l'algorisme.

Implementació[modifica | modifica el codi]

Per a implementar aquest patró cal tenir en compte els següents detalls:

  • És recomanable declarar les operacions primitives de tal manera que només puguin ser cridades pel mètode plantilla (protected si es treballa en Java).
  • Cal reduir al màxim el nombre d'operacions primitives que seran invocades des del mètode plantilla. D'aquesta manera es reduirà la complexitat de les subclasses i, per tant, la implementació serà més fàcil.

Exemple d'implementació en Java[modifica | modifica el codi]

Per implementar el mètode plantilla es vol simular el desplaçament d'un cotxe, que bàsicament es pot simplificar en: accelerar, canviar de marxa i frenar. El procés d'accelerar i frenar es pot considerar que és idèntic en tots els cotxes, i ha diferencia en la forma canviar de marxa que varia d'uns als altres, els cotxes amb canvi manual i els de canvi automàtic.

Podem considerar una superclasse Cotxe en la que es defineix el mètode plantilla (Template Method) desplaçar, des del que es crida a l'operació primitiva canviarMarxa(), que és implementada d'una forma en la subclasse CotxeManual i de forma diferent en la subclasse CotxeAutomatic.

Patró Template method.PNG
ClasseCotxe.PNG
ClasseCotxeAutomatic.PNG
ClasseCotxeManual.PNG
ClassePrincipal.PNG

El resultat de l'execució del programa és el següent:

ResultatExecusio.PNG


Patrons relacionats.

El mètode plantilla es relaciona freqüentment amb els següents patrons de disseny:

  • Strategy Method. Els mètodes plantilla fan servir l'herència per variar el comportament d'un algorisme. En el cas del patró Strategy es fa servir la delegació i es modifica l'algorisme sencer.
  • Factory Method.  Els mètodes Factory (fabricació) solen ser cridats des del mètode plantilla.

Exemple[modifica | modifica el codi]

/**
 * An abstract class that is common to several games in
 * which players play against the others, but only one is
 * playing at a given time.
 */

public abstract class Joc{

    protected int torn;
    abstract void inicialitzarJoc();
    abstract void ferJugada(int player);
    abstract boolean fiJoc();
    abstract void mostrarGuanyador();

    /* A template method */
    public final void jugar(int torn) {
        this.torn = torn;
        inicialitzarJoc();
        int j = 0;
        while (!fiJoc()) {
            ferJugada(j);
            j = (j + 1) % torn;
        }
        mostrarGuanyador();
    }
}

//Now we can extend this class in order 
//to implement actual games:

public class Monopoli extends Joc {

    /* Implementation of necessary concrete methods */
    public void inicialitzarJoc() {
        // Inicialitzar jugadors
        // Inicialitzar diners inicials
    }
    public void ferJugada(int jugador) {
        // Fer una tirada
    }
    public boolean fiJoc() {
        // Retorna true si el joc a finalitzat
        // segons les regles del Monopoliu
    }
    public int intGuanyador() {
        // Mostra qui guanya

    }
    /* Altres funcions del joc. */

    // ...
}

public class Trivial extends Joc {

    /* Implementation of necessary concrete methods */
    public void inicialitzarJoc() {
        // Initialize players
        // Put the pieces on the board
    }
    public void ferJugada(int player) {
        // Process a turn for the player
    }
    public boolean fiJoc() {
        // Return true if in Checkmate or 
        // Stalemate has been reached
    }
    public void mostrarGuanyador() {
        // Mostrar el guanyador
    }
    /* Altres funcions del joc. */

    // ...
}

Bibliografia[modifica | modifica el codi]