Deep Dive into Behavioral Patterns - The Template Method Pattern.

Hey software designers! Today, we’re diving into the Template Method pattern. This pattern is essential for defining the skeleton of an algorithm in a base class but allowing subclasses to override specific steps without changing the algorithm’s structure. Let’s explore its workings, benefits, and real-world applications with detailed examples.

What is the Template Method Pattern?

The Template Method pattern is a behavioral design pattern that defines the skeleton of an algorithm in a base class but allows subclasses to override specific steps without changing the algorithm’s structure. This pattern is particularly useful for creating reusable and customizable algorithms.

Real-World Scenario

Imagine you’re developing a data processing application that needs to process different types of data (e.g., CSV, XML, JSON). Each data type has its specific processing steps, but the overall structure of the processing algorithm remains the same.

The Problem

When different data types need to be processed using a similar algorithm, directly implementing the algorithm within each data type class can lead to duplicated and inflexible code. This approach makes it difficult to maintain and extend the algorithm.

Without Template Method Pattern

class CSVProcessor
  def process
    read_data
    parse_data
    format_data
    save_data
  end

  def read_data
    puts 'Reading CSV data'
  end

  def parse_data
    puts 'Parsing CSV data'
  end

  def format_data
    puts 'Formatting CSV data'
  end

  def save_data
    puts 'Saving CSV data'
  end
end

class XMLProcessor
  def process
    read_data
    parse_data
    format_data
    save_data
  end

  def read_data
    puts 'Reading XML data'
  end

  def parse_data
    puts 'Parsing XML data'
  end

  def format_data
    puts 'Formatting XML data'
  end

  def save_data
    puts 'Saving XML data'
  end
end

csv_processor = CSVProcessor.new
csv_processor.process

xml_processor = XMLProcessor.new
xml_processor.process

Drawbacks: The code is duplicated and difficult to maintain.

The Solution: Template Method Pattern

Using the Template Method pattern, we can define the skeleton of the algorithm in a base class and allow subclasses to override specific steps, promoting code reuse and flexibility.

With Template Method Pattern

Step 1: Define the Base Class

class DataProcessor
  def process
    read_data
    parse_data
    format_data
    save_data
  end

  def read_data
    raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
  end

  def parse_data
    raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
  end

  def format_data
    raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
  end

  def save_data
    raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
  end
end

Step 2: Create Concrete Subclasses

class CSVProcessor < DataProcessor
  def read_data
    puts 'Reading CSV data'
  end

  def parse_data
    puts 'Parsing CSV data'
  end

  def format_data
    puts 'Formatting CSV data'
  end

  def save_data
    puts 'Saving CSV data'
  end
end

class XMLProcessor < DataProcessor
  def read_data
    puts 'Reading XML data'
  end

  def parse_data
    puts 'Parsing XML data'
  end

  def format_data
    puts 'Formatting XML data'
  end

  def save_data
    puts 'Saving XML data'
  end
end

Step 3: Implement the Client Code

csv_processor = CSVProcessor.new
csv_processor.process

xml_processor = XMLProcessor.new
xml_processor.process

Benefits: Defines the skeleton of the algorithm in a base class and allows subclasses to override specific steps, promoting code reuse and flexibility.

Real-World Benefits

Scenario: Adding New Data Types

Imagine you need to add a new data type (e.g., JSON). Using the Template Method pattern, you can easily introduce a new subclass without modifying the existing code.

Without Template Method Pattern:

class JSONProcessor
  def process
    read_data
    parse_data
    format_data
    save_data
  end

  def read_data
    puts 'Reading JSON data'
  end

  def parse_data
    puts 'Parsing JSON data'
  end

  def format_data
    puts 'Formatting JSON data'
  end

  def save_data
    puts 'Saving JSON data'
  end
end

json_processor = JSONProcessor.new
json_processor.process

Drawbacks: Duplicated code that is difficult to maintain and extend.

With Template Method Pattern:

class JSONProcessor < DataProcessor
  def read_data
    puts 'Reading JSON data'
  end

  def parse_data
    puts 'Parsing JSON data'
  end

  def format_data
    puts 'Formatting JSON data'
  end

  def save_data
    puts 'Saving JSON data'
  end
end

json_processor = JSONProcessor.new
json_processor.process

Benefits: Clean, maintainable code with high flexibility and extensibility.

Conclusion

The Template Method pattern is a powerful tool for defining the skeleton of an algorithm in a base class but allowing subclasses to override specific steps. It promotes flexibility, scalability, and maintainability in your code. By using the Template Method pattern, you can easily manage similar algorithms within your applications without duplicating code. Incorporate the Template Method pattern into your design strategies to build more robust and adaptable software systems.

Stay tuned for more insights into software design principles and patterns.

Thôi Lo Code Đi Kẻo Sếp nạt!!