Design Patterns in Ruby: Strategy Pattern
Tags: ruby, designpatterns, strategy
Published: 2018-08-24 01:18:36

---
title: Design Patterns in Ruby: Strategy Pattern
published: true
description: Learn how to apply the Strategy pattern in your ruby code
tags: [ruby, design patterns, strategy]
--- 

> By definition, the Strategy Pattern defines a family of an algorithm and encapsulate each of them in you own class, that way it will enable that the strategy can be interchanged.

In other words, the pattern allows the main algorithm to vary independently of the clients that use it.

It's very similar to [Template Method](https://medium.com/@lccezinha/design-patterns-in-ruby-template-method-pattern-5fd2dcbe15ea) but it uses a different approach, it prefers to use [Composition over Inheritance](https://medium.com/humans-create-software/composition-over-inheritance-cb6f88070205).

To get a start, imagine that exist a `Parser` class that is responsible to parse texts to different formats, initially `JSON` and `XML`.

```ruby
class TextParser
  attr_accessor :text, :parser

  def initialize(text, parser)
    @text   = text
    @parser = parser
  end

  def parse
    if parser == :json
      "{ text: #{text} }"
    elsif parser == :xml
      "<text>#{text}</text>"
    end
  end
end

parser_xml = TextParser.new('My Text', :xml)
parser_xml.parse => "<text>My Text</text>"

puts "\n -- \n"

parser_json = TextParser.new('My Text', :json)
parser_json.parse => "{ text: My Text }"
```

The solution seems to work fine, but uses an `if` to define which `strategy` to format the text. It's not a good approach, for the same reasons that I already explained in [Template Method](https://medium.com/@lccezinha/design-patterns-in-ruby-template-method-pattern-5fd2dcbe15ea) post. 

If we need to add a new (or many others) parsers? Are we going to add a lot of `ifs` to check each parser? I won't scale and doesn't conform with [Open Closed Principle](https://robots.thoughtbot.com/back-to-basics-solid)

We need a better approach, that will allow a flexible way to add new parsers, without the need to change the existent code.

## Use the right Strategy to contemplate many parsers

The `Template Method`, could solve this, but the approach of use Inheritance is not that we want. Inheritance has certain problems:

- Make the code very coupled
- Does not favor encapsulation

The Strategy Pattern will provide us a nice approach that will avoid the problems above and will conform the Open Closed Principle from SOLID (that I plan to talk in a future post).

At first, to solve the problem and give to the code more flexibility, the `TextParser#parse` method will only be responsible to delegate the call of `parser` method to a given class, each of these concrete classes, (JSONParser or XMLParser) will contain their own behavior to implement the `parse` method and will be injected through the `TextParser` constructor as a dependency.

```ruby
class BaseParser
  def parse(text)
    raise 'Must implement!'
  end
end

###

class XMLParser < BaseParser
  def parse(text)
    "<text>#{text}</text>"
  end
end

###

class JSONParser < BaseParser
  def parse(text)
    "{ text: #{text} }"
  end
end

###

class TextParser
  attr_reader :text, :parser

  def initialize(text, parser)
    @text = text
    @parser = parser
  end

  def parse
    puts(parser.parse(text))
  end
end

parser_xml = TextParser.new('My Text', XMLParser.new)
parser_xml.parse => "<text>My Text</text>"

puts "\n -- \n"

parser_json = TextParser.new('My Text', JSONParser.new)
parser_json.parse => "{ text: My Text }"
```

First of all, I created a `BaseParser` class with an abstract method that must be implemented by the subclasses, the main intent of `BaseParser` here, is to "simulate" an `interface`, and guarantee that all subclasses will be required to implement these interface.

But, as Ruby is a dynamic language that uses Duck Typing as an approach to check if a given message must be executed or not for the receiver, we can get rid of these base class and use only the concrete parsers, the result must be the same.

```ruby
class XMLParser
  def parse(text)
    "<text>#{text}</text>"
  end
end

###

class JSONParser
  def parse(text)
    "{ text: #{text} }"
  end
end

###

class TextParser
  attr_reader :text, :parser

  def initialize(text, parser)
    @text = text
    @parser = parser
  end

  def parse
    puts(parser.parse(text))
  end
end

parser_xml = TextParser.new('My Text', XMLParser.new)
parser_xml.parse => "<text>My Text</text>"

puts "\n -- \n"

parser_json = TextParser.new('My Text', JSONParser.new)
parser_json.parse => "{ text: My Text }"
```

With this approach is really simple to add new behaviors, for example, if I need to add a new parser, I just need to create the new parser code that implements the `parse` method, and everything will continue to work:

```ruby
class ReverseParser
  def parse(text)
    text.reverse
  end
end

parser_xml = TextParser.new('My Text', ReverseParser.new)
parser_xml.parse => "txeT yM"
```

Besides, the Strategy Pattern will favor the use of Composition over Inheritance and the code will be in accordance with [Open Closed Principle](https://robots.thoughtbot.com/back-to-basics-solid).

Well, that’s it, now you can create how many parsers do you need. This is how to use the Strategy pattern with Ruby.

Check out the full [source code](https://github.com/lccezinha/random-stuff/tree/master/patterns/strategy-pattern).

## References

- [Reefpoints - Strategy Pattern](http://reefpoints.dockyard.com/2013/07/25/design-patterns-strategy-pattern.html)
- [Open/Closed Principle from SOLID](https://robots.thoughtbot.com/back-to-basics-solid)