DEV Community

kroolar
kroolar

Posted on • Updated on • Originally published at Medium

Ruby Design Patterns | ADAPTER ๐Ÿ”Œ

Overview

The adapter is a structural design pattern that allows two objects with incompatible interfaces to work together.

Real World Example

Before I explain what it is and how to use the adapter pattern, think about what this name associates you with. If youโ€™ve ever been to a country that uses other electrical sockets, you must have used an adapter similar to the one in the picture below.

Image description

So what is the purpose of using an adapter? The adapter allows you to connect a plug(Adaptee) to an electrical socket(Target) that do not fit together.

Coding Problem

First, we will create a simple User class that has two attributes, first_name and last_name, and a full_name method that returns the full name of the user.

class User
  attr_reader :first_name, :last_name

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end

  def full_name
    "#{first_name} #{last_name}"
  end
end
Enter fullscreen mode Exit fullscreen mode

Now we want to prepare a class that will greet new users, so let's create a Greeter class with a hello method that will allow us to greet the user.

class Greeter
  def self.hello(user)
    puts "Hello, #{user.full_name}!"
  end
end

mike = User.new('Michael', 'Scott')
Greeter.hello(mike) # => Hello, Michael Scott!
Enter fullscreen mode Exit fullscreen mode

As we can see, everything in the example above works fine. Now letโ€™s assume that we also want to say hello to new teams.

First we need to create a Team class.

class Team
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

development = Team.new('Development')
Greeter.hello(development) # NoMethodError: undefined method `full_name'
Enter fullscreen mode Exit fullscreen mode

The method will of course raise an error because the Team class doesnโ€™t have a method that returns the full name.

Solution

Before we create a solution to this problem, we need to define three objects that we need in the Adapter pattern.

Target

The object we want to use. In this case, it will be the Greeter class.

Adaptee

The object we want to adapt to work with the target. In this case, it will be the Team class.

Adapter

An object that allows Adaptee to connect to a Target.

If we have already defined Target and Adaptee objects, we can prepare our Adapter class. To create it, just wrap Adaptee(Team) with a new class(Team Adapter) and then create a method(full_name) that will be compatible with the Greeter class interface.

class TeamAdapter
  attr_reader :team

  def initialize(team)
    @team = team
  end

  def full_name
    "#{team.name} Team"
  end
end
Enter fullscreen mode Exit fullscreen mode

An adapter written in such a way can easily be used to work with the Greeter class.

dev_adapter = TeamAdapter.new(development)
Greeter.hello(dev_adapter) # => "Hello, Development Team!"
Enter fullscreen mode Exit fullscreen mode

Top comments (0)