Makeup is the classic adapter; it converts the interface of
the actor (facial-makeup for actors and body-airbrushing for models) into the
interface expected (perfect pretty people) by their client (viewers/audience).
Behind the scenes, a car’s odometer converts the number of
turns of the wheel into a representation of the number of miles the driver has traveled.
How does it do this? A cable runs from the gearbox up to the dash-board of
the car and turns a series of minute gears called cog-wheels. Naturally, since
the engine is turning the gears in the gearbox, it also turns the speedo-cable
and for every couple of hundred turns of the wheel, the mile-digit of the odometer
kicks over and shows a mile. The speedometer is a bit trickier. Based on
Faraday’s principle, electromagnets within the speedometer (again turned by the
speedo-cable) turn past a stationary magnet. The faster the cable spins, the
faster the magnets crash through the stationary magnetic field and the greater
the voltage induced in the electromagnet. Your speedometer cable is in effect
a crude electricity generator/voltmeter since the speedo-needle simply measures
the voltage induced in the magnet.
By now you are wondering whether this tutorial has gone 50
mph down the wrong road. Not quite, you see another adapter that many folks
will be familiar with is the speedometer and odometer. These devices do several
adaptations behind the scenes in a manner which makes for seamless
interpretation of speed and distance traveled respectively. But in reality,
they are not measuring speed, but the number of turns of the wheel. This is
why if you jack up the car and turn the wheel, your “speed” seems to go from 0
to 10mph or so.
This illustrates the workings of the adapter pattern quite
nicely. Supposing I said my 14 year old carbureted car (properly tuned) gives
me 31,000 wheel-turns per gallon in the city/43000 WTPG on the highway. Admit
it, you would be quite perplexed. However, if I told you that I got 24 mpg
city/33 Highway then you would respond without thinking, “That piece of junk
gives such great mileage?" I would be offended, but complimented simultaneously
since I love my old car and feel quite proud that I can keep it running well. You
see, the great job of adaptation which the odometer does allows you the
listener to be able to relate to fuel efficiency when it is measured in miles
per gallon. You think in miles, you calculate your trip in miles; you
calculate your trip costs in miles. And so the odometer adapts the
wheel-revolutions to a figure you can relate to and work with in a meaningful
way.
In the adapter pattern, there is an adaptee class. This
class has an interface which clients cannot be expected to work with for one
reason or the other. In most descriptions of the pattern its incompatibility
is because the client has already been wired-up to interact with some other
interface. In our scenario, the adaptee is the wheel. The interface which the
wheel exposes is the wheel-turn-rate. It is the job of the cable/cog-wheels to
capture the wheel turn rate and turn it into something readable by humans. Similarly,
in the adapter pattern the adapter inherits the interface which is un-readable
and presents an interface which is readable. In the speedometer example we
have one final item and this is the speedometer/odometer display. This is the
public and visible interface which the driver will glance at frantically when
he sees the policeman pointing something at him. He will brake until the
speedometer shows him going a speed within the legal limit. Similarly, in the
adapter pattern the Target is the interface which the client will be able to
interact with and do useful work through.
The client in the adapter pattern interacts with the target
interface. This is mirrored in the motoring situation where the driver (the
client) reads the speedometer (target interface).
Putting it all together, we have an adaptee class which
clients do not know how to work with, an adapter class which is configured with
the interface of the adaptee and so uses the adaptee’s outputs as its inputs. Finally,
it has a public interface which is useful to the client and so the client
interacts with the adapter through public interface it exposes and gets the
adapted outputs.
In fact any device or system which performs conversion shows
the intent and operation of the adapter pattern. The adapter pattern could have
easily been called the converter pattern.
There is a trick in all of this speed business. Did you
know that changing the size of your tires will change the accuracy of your
speedometer and odometer? This is due to the fact that 50mph always translates
to a fixed wheel turn rate. This is unchangeable. However, with bigger tires,
every turn of your wheel means you are actually covering more distance. So
your odometer, trip-meter, speed and mpg calculations all get thrown off with a
changing tire size. Technically, the fact that your tires experience
tread-wear means that there is also minute and very gradual variation in all
the above measures as time goes by. This brings up an important point. In
some cases, adapters may need to be calibrated (see the pattern-tweaking
section).
In the GoF world, we actually have two major types of
adapters. The class adapter inherits publicly from the target class and
privately from the adaptee class. In C++ you can do multiple inheritances, but
not so in VB.NET. So in VB.NET we publicly implement the interface of the
adapter and privately inherit the target class.
In the case of object adapters, we inherit publicly from the
target interface while containing an object reference to the adaptee.