Template Method Design Pattern in R

1. Definition

The Template Method Design Pattern defines the program skeleton in an algorithm in a method in an algorithm, but delays some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm's structure.

2. Problem Statement

Imagine you're creating an application that requires a series of steps to be performed in a specific order, but while the order remains constant, some steps might be implemented differently depending on the context.

3. Solution

The Template Method Pattern solves this by defining a template method that outlines the steps with their order in a base class, and then allows subclasses to provide specific implementations for some of these steps without changing the overall order.

4. Real-World Use Cases

1. A cooking app where the steps for cooking remain the same, but the ingredients or method of cooking might vary.

2. In a software build system where the build and deploy steps remain consistent, but pre or post build steps may vary.

3. Standardized data processing pipelines where preprocessing or cleaning might differ based on the data source.

5. Implementation Steps

1. Define a base class with a template method.

2. The template method consists of steps, some of which are common and some are abstract.

3. Concrete classes provide specific implementations for the abstract steps.

6. Implementation in R Programming

# Step 1: Define the base class with a template method
CookingTemplate <- setRefClass("CookingTemplate",
  methods = list(
    cook_dish = function() {
      prepare_ingredients()
      cook()
      serve()
    },
    prepare_ingredients = function() { cat("Common method to prepare ingredients.\n") },
    cook = function() {},  # Abstract method
    serve = function() { cat("Serving the dish.\n") }
  )
)
# Step 2: Concrete classes
PastaRecipe <- setRefClass("PastaRecipe", contains = "CookingTemplate",
  methods = list(
    cook = function() {
      cat("Boiling pasta and adding sauce.\n")
    }
  )
)
SaladRecipe <- setRefClass("SaladRecipe", contains = "CookingTemplate",
  methods = list(
    cook = function() {
      cat("Mixing vegetables and adding dressing.\n")
    }
  )
)
# Client Code
pasta <- PastaRecipe$new()
pasta$cook_dish()
salad <- SaladRecipe$new()
salad$cook_dish()

Output:

Common method to prepare ingredients.
Boiling pasta and adding sauce.
Serving the dish.
Common method to prepare ingredients.
Mixing vegetables and adding dressing.
Serving the dish.

Explanation:

1. The CookingTemplate class provides a method cook_dish that defines the steps in the order they need to occur.

2. Some methods (prepare_ingredients and serve) have a default implementation.

3. The cook method is abstract, implying that subclasses should provide their implementation.

4. PastaRecipe and SaladRecipe are concrete classes providing specific implementations for the cook method.

5. The client code invokes cook_dish for both recipes, ensuring that the order of the steps remains consistent while the cooking step varies.

7. When to use?

Use the Template Method Design Pattern when:

1. The high-level outline of an algorithm is to remain constant, but individual steps might change.

2. Common behavior among subclasses should be moved to a single class to avoid code duplication.

3. You want to provide hooks (in the form of specific methods) that subclasses can implement.

This pattern promotes code reusability and provides a clear template for processes and workflows.


Comments