Learning Design Patterns – Adapter Pattern

This week I'll be switching over to the Adapter Pattern in my series on design patterns plucked from this book and from examples on the Internet.

What is it?
I remember when I was about 6 I was helping Dad replace a section of board-fence with chain-link fencing (by helping, I mean I was standing there picking my nose and asking him inane questions). He had taken the old fence out, which left three round holes in the ground where the fence posts were. Maybe to quiet me, or maybe just because he enjoys being ornery, he asked if I could explain how those square fence posts had fit into the round holes we were staring at. That question stumped me for years (I blame that on all the lead buckshot I ingested from the pheasants Dad hunted), but now I see that the Adapter Pattern is the answer (or not, but it makes a good story, right!?)

The Adapter Pattern converts one interface into another so that two classes can work together without having to change their code. The most common analogy would be any electronic adapter you can think of; one that converts a US plug to a European plug (you could combine this with the Decorator Pattern to add status lights and other features), or a big headphone jack to a small headphone jack.

There are actually two flavors of the pattern, the Object Adapter, which I'll cover today, and the Class Adapter, which I'll leave to your investigation in the interest of brevity. Suffice it to say, the class Adapter uses multiple inheritance (not possible in Java) and subclasses to adapt, while the Object Adapter uses composition to pass the requests through.

Where is it used?
The Adapter Pattern can be used to connect old code to new code. Maybe you have an existing code base that has a set interface for something, and you buy a 3rd party tool that you'd like to plug into, but that uses a different interface. Instead of rewriting your old code to match the new tool, you could write an adapter to sit between the two.

But why?
Why not just rewrite one of the interfaces and the code that is associated with it so that no adapter is needed? You would have to weigh the risk in opening up new code which can lead to unexpected consequences (bugs) against writing an adapter and handling all the interface handshakes.

Maybe you have some newer code that is programmed to a new interface, and some older code that uses the old interface, what would you do then? You could create a two-way adapter that supports both interfaces.

OK, and how is it implemented?

//Java


//We have an old outlet that only accepts two-pronged plugs
public interface UngroundedOutlet {
	public void TwoProngPlugin();
	public void TwoProngUnplug();
}


//And our new plug has three prongs
public class GroundedPlug {
	public void ThreeProngPlugin();
	public void ThreeProngUnplug();
}

//so we develop an adapter to allow the grounded plug to plugin to the
//ungrounded outlet
public class GroundedAdapter implements UngroundedOutlet {
	GroundedPlug plug;

	public GroundedAdapter(GroundedPlug plug) {
		this.plug = plug;
	}

	public void TwoProngPlugIn() {
		plug.ThreeProngPlugin();
	}


	public void TwoProngUnplug() {
		plug.ThreeProngUnplug();
	}
}

//Now to test it:
public class testPlug {
	public static void main(String[] args) {
		//create the three-prong plug
		Plug groundedPlug = new GroundedPlug();
		//create the adapter
		UngroundedOutlet adapter = new GroundedAdapter(groundedPlug);
		//plug in the adapter to the outlet
		adapter.TwoProngPlugIn();

	}
}