Design Pattern : Adapter in Java

The adapter pattern is a structural design pattern that allows you to repurpose a class with a different interface, allowing it to be used by a system which uses different calling methods.

Adopter Design pattern

 

A square peg in a round hole

A square peg in a round hole

 

The Adapter pattern translates one interface for a class into a compatible interface. It is used when two classes could conceptually work together but cannot because of implementation details. For this example, I create a few simple classes modeling the problem of fitting a square peg into a round hole. A square peg will sometimes fit into a round hole, as illustrated in figure depending on the relative sizes of the peg and the hole:

 

 

To determine if a square will fit into a circle, I use the formula shown here



Figure 2. Formula for determining if a square will fit into a circle

I could trivially solve the square peg/round hole problem with a simple utility class that handles conversions. But it exemplifies a larger problem. For example, what if I’m adapting a Button to fit on a type of Panel that it wasn’t designed for yet can be made compatible with? The problem of square pegs and round holes is a convenience simplification of the general problem addressed by the Adapter design pattern: adapting two incompatible interfaces. To enable square pegs to work with round holes, I need a handful of classes and interfaces to implement the Adapter pattern, as shown in Listing 1:

 

Listing 1. Square pegs and round holes in Java

 

public class SquarePeg {

private int width;

 

public SquarePeg(int width) {

this.width = width;

}

 

public int getWidth() {

return width;

}

}

 

public interface Circularity {

public double getRadius();

}

 

public class RoundPeg implements Circularity {

private double radius;

 

public double getRadius() {

return radius;

}

 

public RoundPeg(int radius) {

this.radius = radius;

}

}

 

public class RoundHole {

private double radius;

 

public RoundHole(double radius) {

this.radius = radius;

}

 

public boolean pegFits(Circularity peg) {

return peg.getRadius() <= radius;

}

}

 

To reduce the amount Java code, I’ve added an interface named Circularity to indicate that the implementer has a radius. This lets me write the RoundHole code in terms of round things, not just RoundPegs. This is a common concession in the Adapter pattern to make type resolution easier.

To fit square pegs into round holes, I need an adapter that adds Circularity to SquarePegs by exposing a getRadius() method, as shown in Listing 2:
Listing 2. Square peg adapter

 

public class SquarePegAdaptor implements Circularity {

private SquarePeg peg;

 

public SquarePegAdaptor(SquarePeg peg) {

this.peg = peg;

}

 

public double getRadius() {

return Math.sqrt(Math.pow((peg.getWidth()/2), 2) * 2);

}

}

 

To test that my adapter does in fact let me fit suitably sized square pegs in round holes, I implement the test shown in Listing 3:
Listing 3. Testing adaptation

 

@Test

public void square_pegs_in_round_holes() {

RoundHole hole = new RoundHole(4.0);

Circularity peg;

for (int i = 3; i <= 10; i++) {

peg = new SquarePegAdaptor(new SquarePeg(i));

if (i < 6)

assertTrue(hole.pegFits(peg));

else

assertFalse(hole.pegFits(peg));

}

}

 

In Listing 3, for each of the proposed widths, I wrap the SquarePegAdaptor around the creation of the SquarePeg, enabling hole’s pegFits() method to return an intelligent evaluation as to the fitness of the peg.

This code is straightforward, because this is a simple albeit verbose pattern to implement in Java. This paradigm is clearly the GoF design-pattern approach. However, the pattern approach isn’t the only way.

UML

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s