Introducció al Patró Template Method

El patró Template Method és un patró de disseny de comportament que defineix l'esquelet d'un algorisme en una operació, delegant alguns passos a subclasses. Permet a les subclasses redefinir certs passos d'un algorisme sense canviar l'estructura de l'algorisme.

Característiques Clau

  • Definició d'Esquelet: El patró defineix l'esquelet d'un algorisme en una operació.
  • Delegació a Subclasses: Permet que les subclasses redefineixin certs passos de l'algorisme.
  • Control de Flux: El mètode template controla el flux de l'algorisme, mentre que les subclasses implementen els detalls.

Estructura del Patró Template Method

Classes i Mètodes

  • Classe Abstracta: Defineix el mètode template i els mètodes abstractes que seran implementats per les subclasses.
  • Mètode Template: Defineix l'esquelet de l'algorisme, cridant als mètodes abstractes.
  • Subclasses: Implementen els mètodes abstractes definits per la classe abstracta.

Diagrama UML

+-------------------+
| AbstractClass     |
+-------------------+
| +templateMethod() |
| +operation1()     |
| +operation2()     |
+-------------------+
        ^
        |
+-------------------+
| ConcreteClass     |
+-------------------+
| +operation1()     |
| +operation2()     |
+-------------------+

Exemple Pràctic

Descripció de l'Exemple

Suposem que volem crear un sistema per preparar diferents tipus de begudes. Utilitzarem el patró Template Method per definir l'esquelet del procés de preparació de la beguda, i deixarem que les subclasses implementin els passos específics per cada tipus de beguda.

Implementació en Codi

Classe Abstracta

abstract class Beverage {
    // Mètode Template
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    // Mètodes abstractes que seran implementats per les subclasses
    abstract void brew();
    abstract void addCondiments();

    // Mètodes comuns
    void boilWater() {
        System.out.println("Boiling water");
    }

    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}

Subclasse per a Te

class Tea extends Beverage {
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}

Subclasse per a Cafè

class Coffee extends Beverage {
    @Override
    void brew() {
        System.out.println("Dripping coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}

Prova del Patró

public class TemplateMethodTest {
    public static void main(String[] args) {
        Beverage tea = new Tea();
        tea.prepareRecipe();

        System.out.println();

        Beverage coffee = new Coffee();
        coffee.prepareRecipe();
    }
}

Sortida Esperada

Boiling water
Steeping the tea
Pouring into cup
Adding lemon

Boiling water
Dripping coffee through filter
Pouring into cup
Adding sugar and milk

Exercicis Pràctics

Exercici 1: Implementació d'una Nova Beguda

Implementa una nova classe HotChocolate que segueixi el patró Template Method per preparar xocolata calenta. La preparació ha d'incloure els següents passos:

  1. Bullir aigua.
  2. Barrejar la xocolata en pols amb aigua calenta.
  3. Abocar en una tassa.
  4. Afegir nata muntada.

Solució

class HotChocolate extends Beverage {
    @Override
    void brew() {
        System.out.println("Mixing hot chocolate powder with hot water");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding whipped cream");
    }
}

Exercici 2: Personalització del Mètode Template

Modifica la classe Beverage per permetre que els usuaris decideixin si volen afegir condiments o no. Afegeix un mètode customerWantsCondiments() que retorni true per defecte, però que pugui ser sobreescrit per les subclasses.

Solució

abstract class Beverage {
    // Mètode Template
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    // Mètodes abstractes que seran implementats per les subclasses
    abstract void brew();
    abstract void addCondiments();

    // Mètodes comuns
    void boilWater() {
        System.out.println("Boiling water");
    }

    void pourInCup() {
        System.out.println("Pouring into cup");
    }

    // Hook method
    boolean customerWantsCondiments() {
        return true;
    }
}

Prova del Nou Mètode Template

class TeaWithoutCondiments extends Tea {
    @Override
    boolean customerWantsCondiments() {
        return false;
    }
}

public class TemplateMethodTest {
    public static void main(String[] args) {
        Beverage tea = new TeaWithoutCondiments();
        tea.prepareRecipe();
    }
}

Sortida Esperada

Boiling water
Steeping the tea
Pouring into cup

Resum

El patró Template Method és una eina poderosa per definir l'esquelet d'un algorisme i permetre que les subclasses implementin els detalls específics. Això promou la reutilització de codi i facilita la mantenibilitat del programari. En aquest mòdul, hem après a implementar el patró Template Method i hem vist com es pot personalitzar per adaptar-se a diferents necessitats.

© Copyright 2024. Tots els drets reservats