Sunday, June 5, 2022

Design Pattern: Adapter Pattern

Chapters

Adapter Pattern

Adapter Pattern is a design pattern that makes two incompatible interfaces collaborate. We use adapter if a new codebase that we wanna add to our application is not compatible with our existing interface.

For example, we have an application that lists data in plain text format. Then, we have a third library that process analytics. This library is verified compatible with our application but the problem is that this library returns data in XML format. To resolve this problem, we can look for another library. However, even we find another library we need to verify if it's compatible with our application, which takes time.

Another solution is to modify the library itself. However, a lot of problems may arise. One of them is licensing issue, some libraries are protected by license and thus we can't just modify libraries. Another solution is to create an adapter which is a good solution to this problem.

There are two types of adapter pattern: Object adapter pattern and Class adapter pattern. Object adapter pattern implements the target(interface where another interface is gonna be converted) interface by delegating to an adaptee(interface that is gonna be converted to) object at run-time.

Class adapter pattern implements the target interface by inheriting from an adaptee class at compile-time. This example demonstrates object adapter pattern.
//client
public class ClientCode{

  public static void main(String[] args){
    PlainTextInterface plainText = 
    new XMLToPlainTextAdapter(new XMLAnalytics());
    
    plainText.displayData();
  }
}

//Assume our third party library has an
//interface
interface XMLInterface{

  String getAnalytics();
}

//Assume this is a third party library
class XMLAnalytics implements XMLInterface{
  private String content;
  
  XMLAnalytics(){
    content= "<data>Testing</data>";
  }
  
  @Override
  public String getAnalytics(){
    return content;
  }
  
}

//Our app's interface
interface PlainTextInterface{

  void displayData();
}

//Our app's class
class PlainTextDisplay implements PlainTextInterface{
  private String data;
  
  PlainTextDisplay(String data){
    this.data = data;
  }
  
  @Override
  public void displayData(){
    System.out.println("Data in plain text: " + data);
  }
}

//Adapter
//In object adapter pattern, we wrap adaptee interface and
//implements target interface
class XMLToPlainTextAdapter implements PlainTextInterface{
  private XMLInterface xml_analytics;
  
  XMLToPlainTextAdapter(XMLInterface xml_analytics){
    this.xml_analytics = xml_analytics;
  }
  
  @Override
  public void displayData(){
    String noTags = 
    xml_analytics.getAnalytics().
    replaceAll("[<][/]??.+?[>]","");
    
    System.out.println("XML converted to plain text");
    System.out.println("Data in plain text: " + noTags);
  }
}

Result
XML converted to plain text
Data in plain text: Testing
Next, let's implement class adapter pattern. First off, change XMLToPlainTextAdapter class to this:
class XMLToPlainTextAdapter 
      extends XMLAnalytics
      implements PlainTextInterface{
  
  @Override
  public void displayData(){
    String noTags = getAnalytics().
    replaceAll("[<][/]??.+?[>]","");
    
    System.out.println("XML converted to plain text");
    System.out.println("Data in plain text: " + noTags);
  }
}
Then, change ClientCode class to this:
public class ClientCode{

  public static void main(String[] args){
    PlainTextInterface plainText = 
    new XMLToPlainTextAdapter();
    plainText.displayData();
  }
}
The problem with class adapter pattern is that it doesn't work with all OOP languages. For example, java doesn't support multiple inheritance of classes; this pattern won't work with java if we have multiple adaptees in one adapter.

In the example above, one-way conversion has been implemented to our adapter. However, we can implement two-way conversion which converts XML to plain text and vice-versa.

To do this, we can implement both interfaces in one adapter or create another adapter for conversion from plain text to XML. In my opinion, the latter is more preferrable.

No comments:

Post a Comment