Real-World Exmple of Adapter Design Pattern

Moving on to the concept of Design Patterns, let's explain the Adapter Design Pattern. This pattern is part of the Structural Design Patterns.

What is Adapter Design Pattern?

According to the GoF's definition, the intent of this  pattern is to:

"Convert the interface of a class into another interface that clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces."

To understand this definition, let's use a  real-world simple example. You know a language, "A". You visit a place where language "B" is spoken. But you don't know how to speak that language. So you meet a person who knows both languages, in other words A and B. So he can act as an adapter for you to talk with the local people of that place and help you communicate with them.

Another example is a kind of situation where the client hires someone to perform a task for him, that he cannot do directly without a third person. This means that the client needs an intermediary to co-ordinate with the third person and get the task done for him. This is what the role of an adapter is. We will be using this example to explain this pattern.

To start with, this pattern can be implemented in one of two ways (or 2 types you can say). We will be explaining both of them along with a real-world example for a better understanding. But before that, we will define the components of our system. They include:

  1. Adaptee: Defines an existing interface that needs adapting; it represents the component with which the client wants to interact with the.
  2. Target: Defines the domain-specific interface that the client uses; it basically represents the interface of the adapter that helps the client interact with the adaptee.
  3. Adapter: Adapts the interface Adaptee to the Target interface; in other words, it implements the Target interface, defined above and connects the adaptee, with the client, using the target interface implementation
  4. Client: The main client that wants to get the operation, is done from the Adaptee.

Now moving on to the types and their implementations.

Class Adapter

A real-world example

You work on a client's projects. You have a team of two developers, A & B (specialist in ASP.NET), who work on this client's project directly, without your involvement. This is important to note here, in other words without your involvement. We will get to why it is so.

So technically, your code will be like the following code:

Image1.jpg

Everything is fine so far. So your client has a new assignment and needs a Silverlight technology to work on. You don't have the team for this technology and don't want to lose the opportunity to work on it So what do you? You create a new team and add members to it.

Since it is a new technology and you have a good hand on Silverlight, you decide to monitor the things yourself and get the task done. So this is where an adapter is useful. You become an adapter and get the things done, by being an intermediate for the client and the new Silverlight team. You get the requirements from the client and pass them to the team and execute the project. So here our adapter is now represented by the ExecuteProject() method in the adapter class. See the code below:

Image2.jpg

This is why I said without your involvement, when I started with the concept. The main requirement that forced us to use an adapter is that the client is not compatible with the new team introduced by you. So you represent yourself to the client, on behalf of your team and get the project done. Here, you bring your team into the picture using the concept of inheritance and in our code, the representations are :

  • Adaptee is SilverlightTeamAdded class
  • Target is represented by ITeams
  • Adapter is represented by the AdapterClass

So this is how to implement the Class adapter. Now moving on to the Object adapter.

Object Adapter

Now since you have completed the first Silverlight project of the client successfully, he is very happy with your performance. So he wants you to handle another project of his. Now that he is quite comfortable with the team, he is ready to deal directly with your team (but with you in the picture of course). So this time, you get the requirements from the client and delegate the responsibility directly to the team. So this is where the basic difference between these two types are. We will explain the differences in detail, after the article. So our code implementation needs a little change and becomes the following:

Image3.jpg

The rest of the code remains the same. You might think that the logically speaking, both the projects are being delegated to the base Silverlight team itself, for completion. Yes, it's correct that both the projects are being executed by the Silverlight team. The next question then is, what is the difference between the two implementations? This is what we will explain next.

Class Adapter vs Object Adapters

The most important difference is that the Class adapter uses the concept of Inheritance, whereas the object adapter uses the concept of Composition.

So when you handled the first project, your team worked under you as an inherited team. In the next project, you just acted as a cover member, and delegated the responsibility to the team, using the concept of composition.
Just a brief explanation, Inheritance and Composition, are very important concepts of Object Oriented Programming and understanding these is very important, if we really want to use an appropriate adapter in our code. Otherwise, we may try to implement the class adapter, where an object adapter can be easily used and vice-versa.

When to use Adapter Pattern

  1. When you have a third-party code that cannot interact with the client code. For example, you might want to use a third-party logger service, but your code is having incompatibility issues, you can use this pattern.
  2. When you want to use an existing code with extended functionality but not without changing it, as it is being used in other components, you can extend it using the adapter pattern.
  3. Again you can use an object adapter for a code, which is using sealed class components, or needs multiple inheritance. For a requirement where you need to use single inheritance, you can choose a class adapter.

So this was all about this Design Pattern.