Whenever and wherever you will read about Adapter pattern you will come across example of electric adapters. Be it a 3-pin to 2-pin adapter, round pin to flat pin adapter or AC to DC adapter, its purpose is to act as an intermediary between electrical equipment and the socket.
Above is a representation of a 3-pin to 2-pin adapter which exposes a 3-pin socket which takes in a 3 pin plug and gives a 2 pin output. (These 2-pins can be plugged into any 2-pin socket.)
Note that the adapter contains a 3-pin plug inside and behavior of its 3 pins is altered to suit the behavior of the adapter pins which will fit in the 2-pin socket.
Now if we interpolate this in terms of Java concepts, the 3-pin socket is an interface and every 3-pin plug implements this interface. Let's call this as 'adaptee' interface. Similarly every 2-pin socket is also an interface which is implemented by every 2-pin plug. Let's call the 2-pin socket (which our adapter is trying to be compatible with) is our target interface.
Let's see some code:
This is our adaptee interface ThreePinSocket:
public interface ThreePinSocket{
public double getPinOneOutput();
public double getPinTwoOutput();
public double getPinThreeOutput();
}
and ThreePinPlug implements it (assuming that top pin gives 1/2 of total input voltage and two bottom pins give 1/4th voltage each)
public class ThreePinPlug implements ThreePinSocket{
int totalInputVoltage;
public ThreePinPlug(int voltage){
totalInputVoltage = voltage;
}
public double getPinOneOutput(){
return totalInputVoltage/2;
}
public double getPinTwoOutput(){
return totalInputVoltage/4;
}
public double getPinThreeOutput(){
return totalInputVoltage/4;
}
}
This is our target interface TwoPinSocket:
public interface TwoPinSocket{
public double getPinOneOutput();
public double getPinTwoOutput();
}
implemented by TwoPinPlug (assuming that both pins give 1/2 of total input voltage each)
public class TwoPinPlug implements TwoPinSocket{
int totalInputVoltage;
public TwoPinPlug(int voltage){
totalInputVoltage = voltage;
}
public double getPinOneOutput(){
return totalInputVoltage/2;
}
public double getPinTwoOutput(){
return totalInputVoltage/2;
}
}
Now let us write the code for our adaptor. Note that it consists of a ThreePinSocket and as we said earlier we are altering the behavior of its pins. So its second pin is now giving 1/2 of total voltage just like any 2 pin plug.
public class ThreeToTwoPinAdaptor implements TwoPinSocket{
ThreePinSocket threePinSocket;
public ThreeToTwoPinAdaptor(ThreePinSocket threePinSocket){
this.threePinSocket = threePinSocket;
}
public double getPinOneOutput(){
return threePinSocket.getPinOneOutput();
}
public double getPinTwoOutput(){
return 2*(threePinSocket.getPinTwoOutput());
}
}
Last piece of this puzzle is the client.
public class AdaptorClient{
public static void main(String args[]){
int inputVoltage = 100;
//create a 2pin plug.
TwoPinSocket twoSock = new TwoPinPlug(inputVoltage);
getTwoPinOutput(twoSock);
//now let's create a 3pin plug.
ThreePinSocket threeSock = new ThreePinPlug(inputVoltage);
System.out.println("Pin1 Output: "+threeSock.getPinOneOutput()+" Pin2 Output: "+threeSock.getPinTwoOutput()+" Pin3 Output: "+threeSock.getPinTwoOutput());
//now we create an adaptor using 3pin plug created earlier
ThreeToTwoPinAdaptor adaptor = new ThreeToTwoPinAdaptor(threeSock);
//Note this adaptor can easily be used in place of 2pin plug!
getTwoPinOutput(adaptor);
}
public static void getTwoPinOutput(TwoPinSocket twoPinSocket){
System.out.println("Pin1 Output: "+twoPinSocket.getPinOneOutput()+" Pin2 Output: "+twoPinSocket.getPinTwoOutput());
}
}
Output:
Pin1 Output: 50.0 Pin2 Output: 50.0
Pin1 Output: 50.0 Pin2 Output: 25.0 Pin3 Output: 25.0
Pin1 Output: 50.0 Pin2 Output: 50.0
Notice that getTwoPinOutput() expects a TwoPinSocket and our adaptor fits it so well!
This was adaptor pattern in action! Let's define it: Adaptor Pattern converts the interface of a class into another interface the clients expect.
Simple and pretty useful isn't it?
Comments