Romman Sabbir
Romman's Blog

Romman's Blog

Adapter - Design Pattern

Adapter - Design Pattern

Design Patterns: Elements of Reusable Object-Oriented Software

Romman Sabbir's photo
Romman Sabbir
·Jan 23, 2022·

2 min read

What is Adapter Pattern?

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

Why Adapter Pattern?

Adapter pattern is typically used when an incompatible module needs to be integrated with an existing module without making any source code modifications.

We can summarize the participants of the adapter pattern in the context of the text formatting example, as:

  • Target (TextFormatter): The existing interface that clients communicate with.
  • Adaptee (CSVFormatter): The new incompatible interface that needs adapting.
  • Adapter (CSVFormatterImpl): A class that adapts the Adaptee to the Target.
  • Client: Communicates with the Target.

Let's Deep Dive Into Adapter Pattern

interface TextFormatter {
    fun formatText(input: String): String
}
class TextFormatterImpl : TextFormatter {
    override fun formatText(input: String): String =
        input.replace(".", "\n")
}

We have an existing interface & implementation of TextFormatter and TextFormattableImpl. This code is from an external vendor and we don't have any right to change it and if we did, we are breaking SOLID programming principles, specially Single Responsibility Principle and Iterface Segregation Principle.

Now, clients want us to develop a new feature called CSV Formatter and we should follow the existing interface from external vendor. So, how do we work both of the old interface and our new implementation?

We can solve this problem by following Adapter Design Pattern.

Let's work on our new subsystem. We have a new interface called CSVFormatter and CSVFormatterImpl.

interface CSVFormatter {
    fun formatText(input: String): String
}
class CSVFormatterImpl : CSVFormatter{
    override fun formatText(input: String): String =
        input.replace(".", ",")
}

And, we want to workout our new subsystem with old subsystem from the external vendor.

Let's create our own adapter for this.

class CSVAdapterImpl constructor
(private val csvFormatter: CSVFormatter) : TextFormatter {
    override fun formatText(input: String): String = csvFormatter.formatText(input)
}

Note: We have implement the old interface from external vendor TextFormatter and we take an instance of CSVFormatter as a parameter to execute our own business logic instead of the Vendor's one. That's the Adapter Pattern where two incompatible subsystem working together.

Let's take a look at the full implementation in Kotlin.

Follow Me on LinkedIn:

 
Share this