Introducing the Adapter design pattern

Introducing the Adapter design pattern

Read Time : 3 Minutes

Friday, 17 March 2023

Design patterns are proven solutions to software design problems. They help improve code quality, promote reusability, and increase maintainability. We use them to save time and produce quality, extensible and flexible code. In this article, we are going to introduce the Adapter design pattern.

Adapter design pattern is a structural design pattern that connects two incompatible classes through an interface class. The Adapter pattern is useful when we want to create a class that can work with multiple incompatible classes.

The Adapter pattern consists of the following items:

  • Target: The interface that the client wants to use.
  • Adaptee: An existing class with an incompatible interface that needs to be adapted.
  • Adapter: A class that connects two Adaptee and Target classes.
  • Client: The class that intends to use the ITarget instance.
adapter

The Adapter pattern can be implemented in two ways:

In the first method, the Adapter class inherits from the Adaptee class and obtains its features and can call its methods.

In the second method, the Adapter class defines an instance of Adaptee in its body that it can use.

In both methods, the Adapter class must implement the Itarget interface.

 

Below is an example of the Adapter pattern in C#:

// Target interface
public interface ITarget
{
    void Request();
}
// Adaptee interface
public interface IAdaptee
{
    void SpecificRequest();
}
// Adaptee implementation
public class Adaptee : IAdaptee
{
    public void SpecificRequest()
    {
       Console.WriteLine("Adaptee method called");
    }
}

Implementation of the first method:

// Class adapter implementation
public class Adapter : Adaptee, ITarget
{
    public void Request()
    {
        SpecificRequest();
    }
}

Implementation of the second method:

// Object adapter implementation
public class ObjectAdapter : ITarget
{
    private IAdaptee _adaptee;
    public ObjectAdapter(IAdaptee adaptee)
    {
        _adaptee = adaptee;
    }
    public void Request()
    {
       _adaptee.SpecificRequest();
    }
}

Using implemented methods:

// Client code
public class Client
{
    public void DoWork(ITarget target)
    {
        target.Request();
    }
}
// Usage
var client = new Client();
// Class adapter usage
var adapter = new Adapter();
client.DoWork(adapter);
// Object adapter usage
var adaptee = new Adaptee();
var objectAdapter = new ObjectAdapter(adaptee);
client.DoWork(objectAdapter);

In this example, we have an ITarget interface that the client uses. We also have an IAdaptee interface that should be adapted to ITarget. The Adaptee class is an implementation of the IAdaptee interface.

The Adapter class is an example that uses the first method of implementing this pattern. This class inherits from the Adaptee class and implements the ITarget interface. Then the Client can receive an instance of the Adapter and call the SpecificRequest method in the Adaptee through the Request method.

The ObjectAdapter class is an example that uses the second method of implementing this pattern. This class implements the ITarget interface and defines an instance object of the Adaptee. In this example, the Client calls the SpecificRequest method by calling the Request method through the object in the Adapter.

 

Finally, we see that without making any direct changes in the codes and only by creating an interface class, the connection between these two classes was possible.

To read about other design patterns, you can use the list below. There is also a code repository on GitHub that includes all the design patterns.

design patterns

Creational:Factory Design Pattern
Builder Design Pattern
Singleton Design Pattern
Prototype Design Pattern
Abstract Factory Design Pattern
Structural:Adapter Design Pattern
Bridge Design Pattern
Composite Design Pattern
Decorator Design Pattern
Facade Design Pattern
Flyweight Design Pattern
Proxy Design Pattern
Behavioral:Chain of Responsibility Design Pattern
Command Design Pattern
Interpreter Design Pattern
Mediator Design Pattern
Memento Design Pattern
Observer Design Pattern
State Design Pattern
Strategy Design Pattern
Template Method Design Pattern
Visitor Design Pattern
Iterator Design Pattern
  • Share:
reza babakhani
Reza Babakhani

I am Reza Babakhani, a software developer. Here I write my experiences, opinions and suggestions about technology. I hope that what I write is useful for you.

Latest post

Service Mesh Simplifying Microservice Communication

In the ever-evolving landscape of software development, microservices architecture has gained considerable popularity due to its scalability, flexibility, and extensibility. However, as the number of microservices in an application increases, it becomes increasingly challenging to manage their communication and ensure that they are all properly visible. This is where Service Mesh comes into play.

The Importance of Edge Computing

Due to the speed of technological evolution, one of the concepts that has attracted a lot of attention and changes the way we interact with digital systems is edge computing.

What is event-driven architecture?

Event-driven architecture (EDA) is a software design pattern that has become increasingly popular in modern software development. In this architecture, the flow of data is determined by the occurrence of events. Unlike traditional centralized systems that are constantly checking for new status. Event-driven architecture is especially useful for systems that need to process large amounts of data in real-time.

leave a comment