Design patterns: Template Method

Mauto 3 min

The Template Method is a behavioral pattern that defines the skeleton of an algorithm inside a method, letting subclasses implement specific parts of the algorithm without changing its overall structure. This pattern lets you reuse code and promotes a clear separation between what is invariant and what varies within the algorithm.

Strengths

  1. Code reuse: The general structure of the algorithm is defined only once in the base class, promoting reuse of common code.
  2. Flexible algorithm definition: Subclasses can change only the specific parts of the algorithm, while the overall sequence stays the same.
  3. Preventing duplication: It reduces code duplication, because the common logic lives in a single base class.
  4. Control over the algorithm’s flow: The base class keeps control over the algorithm’s execution, making it hard for subclasses to alter the order of operations.
  5. Structural clarity: It allows a clear split between generic behavior (base class) and specific behavior (subclasses).

Use case: An online ordering process

Imagine a system for managing online orders. The ordering process follows some common steps: selecting the product, entering shipping details and processing the payment. However, the payment method can vary between credit card and PayPal.

PHP Code

// Abstract class that defines the template method
abstract class OrderProcessTemplate {
    // Template method that defines the algorithm
    public function processOrder() {
        $this->selectProduct();
        $this->addShippingDetails();
        $this->processPayment();
        $this->shipOrder();
    }

    // Required methods to be implemented in subclasses
    abstract protected function selectProduct();
    abstract protected function processPayment();

    // Common method for adding shipping details
    protected function addShippingDetails() {
        echo "Shipping details added.\n";
    }

    // Final method for shipping the order, invariant across subclasses
    protected function shipOrder() {
        echo "Order shipped.\n";
    }
}

// Concrete implementation for an order paid by Credit Card
class CreditCardOrder extends OrderProcessTemplate {
    protected function selectProduct() {
        echo "Product selected.\n";
    }

    protected function processPayment() {
        echo "Payment made by Credit Card.\n";
    }
}

// Concrete implementation for an order paid with PayPal
class PayPalOrder extends OrderProcessTemplate {
    protected function selectProduct() {
        echo "Product selected.\n";
    }

    protected function processPayment() {
        echo "Payment made with PayPal.\n";
    }
}

// Usage example
$order1 = new CreditCardOrder();
$order1->processOrder();  // Ordering process with Credit Card

echo "\n";

$order2 = new PayPalOrder();
$order2->processOrder();  // Ordering process with PayPal

Explanation

  • OrderProcessTemplate class: Defines the Template Method processOrder(), which contains the sequence of operations common to all subclasses. Some methods, such as selectProduct() and processPayment(), are declared abstract, leaving it to the subclasses to implement them.
  • Invariant methods: Methods such as addShippingDetails() and shipOrder() are common to all subclasses and are not meant to be changed.
  • Subclasses (CreditCardOrder, PayPalOrder): Implement the algorithm’s specific details, such as product selection and the payment method.
  • Using the Template Method: The processOrder() method follows the predefined sequence, but the variable parts are delegated to the subclasses.

Conclusion

The Template Method Pattern lets you define the structure of an algorithm in the base class and delegate the implementation of specific details to subclasses. This approach makes the code more modular, reusable, and easy to extend.

BACK TO THE GUIDE

Copiato