The adapter pattern
Purpose
The adapter pattern allows us to create a new interface around an existing class. This is useful when a class has the behaviours we need, but they're implemented in a way that isn't compatible with the rest of our software.
For example, we might have legacy code for older smart lights:
public class OldLight {
public int power;
public OldLight() {
this.power = 1;
}
public void on() {
this.power = 1;
}
public void off() {
this.power = 0;
}
}
Using the adapter pattern, we can wrap this old code in an adapter so that we expose an isOn
property and a togglePower()
method, bringing it in line with the newer SmartLight
interface.
Implementation
First, let's define a common Light
interface that the rest of our application will use:
public interface Light {
boolean isOn();
void togglePower();
}
Next, we'll implement the LightAdapter
class, which adapts an instance of OldLight
to the Light
interface:
public class LightAdapter implements Light {
private OldLight oldLight;
public LightAdapter(OldLight oldLight) {
oldLight.off(); // Make sure it's off by default
this.oldLight = oldLight;
}
@Override
public boolean isOn() {
return oldLight.power == 1;
}
@Override
public void togglePower() {
if (isOn()) {
oldLight.off();
} else {
oldLight.on();
}
}
}
Usage
Now, we can use the LightAdapter
to interact with OldLight
instances through the Light
interface:
public class Main {
public static void main(String[] args) {
OldLight oldLight = new OldLight();
Light adaptedLight = new LightAdapter(oldLight);
System.out.println(adaptedLight.isOn()); // false
adaptedLight.togglePower();
System.out.println(adaptedLight.isOn()); // true
}
}
SmartLight class
To show how the Light
interface can be implemented by new classes, here's a SmartLight
class:
public class SmartLight implements Light {
private boolean power;
public SmartLight() {
this.power = false;
}
@Override
public boolean isOn() {
return power;
}
@Override
public void togglePower() {
power = !power;
}
}
Now, both LightAdapter
(adapting OldLight
) and SmartLight
can be used interchangeably:
public class Main {
public static void main(String[] args) {
Light smartLight = new SmartLight();
LightAdapter adaptedLight = new LightAdapter(new OldLight());
// Using SmartLight
System.out.println(smartLight.isOn()); // false
smartLight.togglePower();
System.out.println(smartLight.isOn()); // true
// Using Adapted OldLight
System.out.println(adaptedLight.isOn()); // false
adaptedLight.togglePower();
System.out.println(adaptedLight.isOn()); // true
}
}