How to Use the Excellent Adapter Pattern and Why You Should
Tags: csharp, programming, coding, beginners
Published: 2018-06-29 16:52:00

---
title: How to Use the Excellent Adapter Pattern and Why You Should
published: true
description: 
tags: #csharp #programming #coding #beginners
cover_image: https://thepracticaldev.s3.amazonaws.com/i/3yuvw5lwlky1ozl8t9c0.png
canonical_url: https://blog.kylegalbraith.com/2018/06/29/how-to-use-the-excellent-adapter-pattern-and-why-you-should/
---
The adapter pattern is classified as a structural pattern that allows a piece of code talk to another piece of code that it is not directly compatible with. 

First, for the sake of the next few minutes let's frame our context within the bounds of a web application we are responsible for. The application is a classic three-tier application, front-end client, web server for the API, and a place to store data. This is a pretty traditional stack nowadays.

Now I want to call out: *a place to store data*. This could be a database like SQL Server or MongoDB. It could also just be a place we dump data like AWS S3 or maybe even our hard drive. 

It is preferable if our application never even cares where we store or read data. If we define a common interface for doing those operations we can change where we store or read data from without the application needing to change. For that, we leverage something the [repository pattern](https://dev.to/kylegalbraith/getting-familiar-with-the-awesome-repository-pattern--1ao3).

The adapter pattern is a pattern that could be used within the repository. It is a pattern that allows your application code to leverage a consistent interface for working with another piece of code without needing to be reliant on that code. To put it even more bluntly for this post, we are going to define an adapter as a common interface for connecting two pieces of disjointed code.

With me so far? It's ok if your not, let's look at when you might use it to try and clear things up.

### Spotting the (potential) need for the adapter pattern
To be franc spotting the potential use of the adapter pattern can sometimes be harder than it sounds. This is often because most modern programming languages already have adapters built into them. But let's pretend we have an `IPerson` interface as defined below.

```csharp
public interface Person : IPerson
{
    public string Name { get; set; }
    public string City { get; set; }
    public string IdNumber { get; set; }
}
```

We then have an old piece of code that has always been responsible for loading the `Person` objects.

```csharp
public class PersonLoader: IPersonLoader
{
    public Person LoadPerson()
    {
        //code to load a person
    }
}
```

Notice here that `PersonLoader` implements a common interface `IPersonLoader` that defines the necessity for a method called `LoadPerson()`. Let's look at the code that is using `PersonLoader`.

```csharp
public class LoadPeople
{
    static void Main(string[] args)
    {
        IPersonLoader loader = new PersonLoader();
        var person = loader.LoadPerson();
    }
}
```

Here the loader is of type `IPersonLoader`, and `PersonLoader` just happens to implement that interface. So a `PersonLoader` is created, and the code can then call `LoadPerson()`. So far so good right?

But remember, `PersonLoader` is a crummy piece of code that we want to move away from without breaking our entire application. Specifically, we want to start loading the `IPerson` objects using a new and improved loader.

What we have here is a great use case for the adapter pattern.

### Adding in the adapter spice
First, we define our new and improved person loader, `BetterPersonLoader` that implements `IBetterPersonLoader` which contains a new method `RunGetPerson()`.

```csharp
public class BetterPersonLoader : IBetterPersonLoader
{
    public Person RunGetPerson()
    {
        //code to get person the new and improved way.
    }
}
```

But we can't just plug in `BetterPersonLoader` into our `LoadPeople` client. It's not compatible and would break that code because that code needs an `IPersonLoader` interface.

So what we can do is define a `PersonAdapter` that implements that interface. Let's see what that would look like.

```csharp
public class PersonAdapter : IPersonLoader
{   
    public Person LoadPerson()
    {
        var newLoader = new BetterPersonLoader();
        return newLoader.RunGetPerson();
    }
}
```

We can then update our `LoadPeople` client to leverage our new adapter.

```csharp
public class LoadPeople
{
    static void Main(string[] args)
    {
        IPersonLoader loader = new PersonAdapter();
        var person = loader.LoadPerson();
    }
}
```

Now, this code is resilient to this change again in the future. If `BestPersonLoader` comes along, we can update our `PersonAdapter` class and the `LoadPeople` client **never needs to be changed**.

```csharp
public class PersonAdapter : IPersonLoader
{   
    public Person LoadPerson()
    {
        var newLoader = new BestPersonLoader();
        return newLoader.BestWayToGetPerson();
    }
}
```

### The pros and the cons
The adapter pattern shows up in a lot of different flavors. You can see it in something as simple as loading data from somewhere. Or you can see it in more complex implementations like in an HTTP client. The adapter pattern introduces a lot of nice benefits:

* It increases reusability and flexibility. The interface of the adapter is defined and agreed upon. So as long as the agreement is maintained we can change the implementation within the adapter.
* Clients become simplified. As we saw in our example after the refactor to an adapter pattern we can now change to any kind of loader logic we want. The client doesn't have to make that decision because the adapter has agreed to the `IPersonLoader` contract.
* Changing and trying new ideas, breaks and changes fewer things. The coupling is minimized to just the agreed upon contract, the implementation of that contract is free to interpretation.

These are stellar benefits, but I would reminisce if I didn't warn you of the potential traps you could fall into.

* The rabbit trail effect. Sometimes adapters can be taken to the extreme if you have deeply nested objects. You can end up with `AdapterA` calling `AdapterB` calling `AdapterC` just to load a Person.
* Prone to over-engineering. Notice in this post I started with a piece of code that **didn't use** the adapter pattern. This is because it is a pattern that often **emerges** and is not known from the outset. Do your best to not try and introduce an adapter pattern when you don't actually need one.

### Hungry To Learn Amazon Web Services?
There is a lot of people that are hungry to learn Amazon Web Services. Inspired by this fact I have created a course focused on learning Amazon Web Services by using it. Focusing on the problem of hosting, securing, and delivering static websites. You learn services like S3, API Gateway, CloudFront, Lambda, and WAF by building a solution to the problem.

There is a sea of information out there around AWS. It is easy to get lost and not make any progress in learning. By working through this problem we can cut through the information and speed up your learning. My goal with this book and video course is to share what I have learned with you.

Sound interesting? Check out the landing page to learn more and pick a package that works for you, [learn AWS basics by actually using it](https://www.kylegalbraith.com/learn-aws/).