pattern-design (8 Part Series)
There are 23 classic design patterns, which are described in the original book,
Design Patterns: Elements of Reusable Object-Oriented Software. These patterns
provide solutions to particular problems, often repeated in the software
In this article, I am going to describe the how the Adapter Pattern; and how
and when it should be applied.
An adapter allows two incompatible interfaces to work together. This is the real-world definition for an adapter. Interfaces may be incompatible, but the inner functionality should suit the need. The adapter design pattern allows otherwise incompatible classes to work together by converting the interface of one class into an interface expected by the clients. — Wikipedia
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. — Design Patterns: Elements of Reusable Object-Oriented Software
The main feature of this pattern is reusing a class which has different interfaces compared with the rest of classes or several classes which have different interface so they can works together.
There are two versions of this pattern:
object adapterimplements the
targetinterface by delegating to an
adapteeobject at run-time.
class adapterimplements the
targetinterface by inheriting from an
adapteeclass at compiler-time.
Since multiple inheritance is not supported by many languages including Java and
is associated with many problems we have not shown implementation using class adapter pattern.
To sum up, the object adapter (AKA adapter) contains an instance of the class it
wraps. The UML’s diagram of this pattern is the following one:
Adaptor class contains the
Adaptee class. Which means
Adaptee class will be used by
- There is a class which its interfaces do not match the one you need.
- There are several subclasses but it’s unpractical to adapt their interface by subclassing every one.
The Adapter Pattern has several advantages, summarised in the following points:
- The code is more resuable and flexible.
- Clean code because the client/context doesn’t use a different interface in each concrete class and can use polymorphism to swap between different adapters.
Warrior which defines a Warrior. A warrior has a set of attributes not relevant to the problem and a method called
attack. There is a classification of types of warriors such as
Namekian which defines a concrete implementation of the
attack method but a new class arrives to the system called
Android which does not satisfy Warrior's interface but internally implemented the method just in different way. The following UML diagram shows the scenario that I have just described.
The solution is to use an adapter pattern that consits in a class (
AndroidAdapter) which contains the
Android object and use it to do it compatible with the warrior's interface. I.e, the new UML diagram using the adapter pattern is shown below:
The code associate to the models and interface are the following ones:
As you can see the
Android class has not implemented the warrior's interface.
So, the class
AndroidAdapter is responsible for solving this problem.
Finally, the client/context that wants to use the three class should use the
AndroidAdapter class together with
Namekian as you can see in the next code:
Another interesting problem which is resolved using Adapter pattern is when there are several classes with different interfaces but they can works together. In the following UML’s diagram you can see this situation:
In this case, the races have different interface to communicate between them. In concrete, each race has one or several methods to shared its power. For example, the humans have
sharedPower and the namekians have
getPower and even more complex are the saiyans which have two methods to shared its power (
The solution to do that several races works together is used the adapter pattern as you can see in the following UML’s diagram.
A new adapter class is used for each class, this adapter class contains the original object and the methods that implements the interface. The code for this example is quite easy.
And their respective adapters are the following:
Finally, all the objects contributing energy to fight evil and achieve great power.
I have created two npm scripts that run the two examples shown here after applying the Adapter pattern.
npm run example1
npm run example2
The most important thing has not implement the pattern as I have shown you, but to be able to recognise the problem which this specific pattern can resolve, and when you may or may not implement said pattern. This is crucial, since implementation will vary depending on the programming language you use.
- Design Patterns: Elements of Reusable Object-Oriented Software by Gamma, Helm, Johnson, & Vlissides, Addison Wesley, 1995.
- The Adapter Pattern — Wikipedia.
- The GitHub branch of this post is https://github.com/Caballerog/blog/tree/master/adapter-pattern
Originally published at www.carloscaballero.io.