The Adapter Pattern in Java

Introduction to the Adapter Pattern

Design pattern in a simple meaning, is a way to design reusable object-oriented code. We can think of ways to design our classes, interfaces, enums and their members so that the code is reusable but flexible.

There are 23 most important design patterns, pioneered by the book Design Patterns: Elements of Reusable Object-Oriented Software, written by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides or Gang of Four for short. We will cover these design pattern one by one.

It may happen that sometimes we try to integrate legacy code with new code, where their interfaces (API) are different. The Adapter pattern helps make the two unrelated interfaces work together.

Implementation of Adapter Pattern in Java

Ok, say we have the Rectangle.java like this:

public class Rectangle {
  private final double height;
  private final double width;
  public Rectangle(double height, double width) {
    this.height = height;
    this.width = width;
  }
  public double getHeight() {
    return height;
  }
  public double getWidth() {
    return width;
  }
}

A simple class that defines a rectangle with the height and width of double type. Next we have an Area class that will calculate the area of a rectangle, the Area.java:

public class Area {
  double getArea(Rectangle rec){
    return rec.getHeight() * rec.getWidth();
  }
}

In Test.java:

public class Test {
  public static void main(String[] args){
    Area area = new Area();
    double a1 = area.getArea(new Rectangle(5, 2));
    System.out.println(
        "The area of rectangle is: " + a1);
  }
}

The code simply output the area of the rectangle with height of 5 and width of 2:

The area of rectangle is: 10.0

Now say we have a new Triangle class, which defines a triangle with height and base. The Triangle.java is like this:

public class Triangle {
  private final double height;
  private final double width;
  public Triangle(double height, double width) {
    this.height = height;
    this.width = width;
  }
  public double getHeight() {
    return height;
  }
  public double getWidth() {
    return width;
  }
}

Now we don’t want to rewrite the Area class, and want to use it to calculate the area of the triangle. But the problem is that the Area’s getArea() method only accepts a Rectangle. Moreover, the area of the triangle is base * height / 2.

We can solve the problem with the Adapter pattern. First we create a RectangleAdapter class. This class will extend the Rectangle class but it must also adapt the Triangle class so that we can pass this class to Area’s getArea() method and get the correct result:

public class RectangleAdapter extends Rectangle{
  public RectangleAdapter(Triangle tri) {
    super(tri.getHeight()/2, tri.getBase());
  }
}

Well this is a naive way, basically it converts the Triangle to a Rectangle with same base (width) but half the height, which are of same area as the Triangle. So in Test.java:

public class Test {
  public static void main(String[] args){
    Area area = new Area();
    double a1 = area.getArea(new Rectangle(5, 2));
    System.out.println(
        "The area of rectangle is: " + a1);
    //
    Triangle triangle = new Triangle(5, 2);
    RectangleAdapter adapter =
        new RectangleAdapter(triangle);
    double triArea = area.getArea(adapter);
    System.out.println(
        "The area of triangle is: " + triArea);
  }
}

Now run the code and we have what we expected:

The area of rectangle is: 10.0
The area of rectangle is: 5.0

Leave a Reply