0% found this document useful (0 votes)
154 views13 pages

Adapter

The Adapter pattern allows classes with incompatible interfaces to work together by wrapping them in an adapter class. The adapter implements the target interface that clients expect, and contains a reference to an instance of the adaptee class. When a request comes in through the target interface, the adapter delegates the request to the adaptee. This allows existing classes to be used even if their interface is not the same as what clients require.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
154 views13 pages

Adapter

The Adapter pattern allows classes with incompatible interfaces to work together by wrapping them in an adapter class. The adapter implements the target interface that clients expect, and contains a reference to an instance of the adaptee class. When a request comes in through the target interface, the adapter delegates the request to the adaptee. This allows existing classes to be used even if their interface is not the same as what clients require.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 13

The Adapter Pattern

Putting a Square Peg in a Round Hole!

Wrapping Objects to Unify Interfaces


Question: What pattern wraps objects to give them new functionality? Now we wrap objects with a different purpose:
To make their interfaces look like something they are not To simplify the interfaces of objects

Adapters
Real world is full of them!
Some examples?

Object oriented adapters


Scenario: you have an existing software system that you need to work a new vendor library into, but the new vendor designed their interfaces differently than the last vendor.
Your Existing System Vendor Class Their interface doesnt match the one youve written your code against. Not going to work!

The adapter implements the interface your classes Your Existing expect System

What to do? Write a class that adapts the new vendor interface into the one youre expecting. And talks to the vendor interface to service
your requests Adapter Vendor Class

==

Your Existing Adapter System New code

Vendor Class No code changes

No code changes

If it walks like a duck..


If it walks like a duck and quacks like a duck, then it might be a duck turkey wrapped with a duck adapter.
public interface Duck { public void quack (); public void fly (); } public class MallardDuck implements Duck { public void quack () { System.out.println(Quack); } public void fly ( ) { System.out.println (I am flying); } }

Meet the fowl!


public interface Turkey { public void gobble (); public void fly ( ); } public class WildTurkey implements Turkey { public void gobble ( ) { System.out.println(Gobble Gobble); } public void fly ( ){ System.out.println(Im flying a short distance); } }

Concrete implementations are similar -- just print out the actions.

Now.
Lets say you are short on Duck objects and would like to use some Turkey objects in their place. Cant use them outright because they have a different interface.
public class TurkeyAdapter implements Duck { Turkey turkey; public TurkeyAdapter (Turkey turkey) { this.turkey = turkey; } Next, we need to get a reference to the object that we public void quack ( ) { are adapting; here we do that through the constructor. turkey.gobble ( ); } public void fly ( ){ Now we need to implement all the methods in the for (int j = 0; j<5; j++) interface; the quack() translation between classes is easy; turkey.fly ( ); just call the gobble method. } } Even though both interfaces have a fly ( ) method, Turkeys fly in } short spurts -- they cant do long distance flying like ducks. To map between a Ducks fly ( ) method and a Turkeys we need to call the Turkeys fly ( ) method five times to make up for it. First, you need to implement the interface of the type you are adapting to. This is the interface your client expects.

The Adapter Pattern Defined


The Adapter Pattern converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldnt otherwise because of incompatible interfaces.

Client
The client sees only the Target interface.

<<Interface>> Target request ( )

The Adapter implements the target interface

Full of good OO design principles: --Use of object composition --Pattern binds the client to an interface and not an implementation

Adapter request ( )

Adaptee specificRequest ()

Adapter is composed with the Adaptee

All requests get delegated to the Adaptee

Object and Class Adapters


There are two types of Adapters
Object Adapter : what we have seen so far. Class Adapter: not as common as it uses multiple inheritance, which isnt possible in Java.
Client <<Interface>> Target request ( ) Adaptee specificRequest ()

Difference: The only difference is that with class adapter we subclass the Target and the Adaptee, while the object adapter uses composition to pass requests to an adaptee.

Adapter request ( )

Question: Object Adapters and Class Adapters use two different means of adapting the adaptee (composition versus inheritance). How do these implementations affect the flexibility of the adapter?

Real World Adapters


Old world Enumerators
<<interface>> Enumeration hasMoreElements ( ) nextElement ( )

Enumeration has a simple interface. Tells whether there are any more elements in the collection. Returns the next element Tells you if you have looked at all the elements Gets the next one

New world Iterators

<<interface>> Iterator hasNext ( ) next ( ) remove ( )

And todaylegacy code that exposes the Enumerator interface. Yet we want new code to use Iterators. Need an adapter.

Removes an item from the collection

Adapting an Enumeration to an Iterator


First step: examine the two interfaces
Target interface These two methods look easy, they map straight to hasNext ( ) and next ( ) in Iterator

<<interface>> Iterator hasNext ( ) next ( ) remove ( )

<<interface>> Enumeration hasMoreElements ( ) nextElement ( )


Adaptee interface

But what about this method remove ( ) in Iterator? Theres nothing like that in Enumeration.

Designing the Adapter


Your new code gets to use Iterators, even if theres really an Enumeration underneath.

<<interface>> Iterator hasNext ( ) next ( ) remove ( )

We are making the Enumerations in your old code look like Iterators for your new code.

A class implementing the Enumeration interface is the adaptee.

EnumerationIterator is the Adapter

EnumerationIterator hasNext ( ) next ( ) remove ( )

<<interface>> Enumeration hasMoreElements () nextElement ()

Dealing with the remove ( ) method


Enumeration is a read only interface - it does not support the remove ( ) method.
Implies there is no real way to implement a fully functioning remove () method. The best that can be done is to throw a runtime exception. Iterator designers foresaw the need and have implemented an UnsupportedOperationException.

Here the adapter is not perfect but is a reasonable solution as long as the client is careful and the adapter is well-documented.

EnumerationIterator - The Code


public class EnumerationIterator implements Iterator { Enumeration enum; public EnumerationIterator (Enumeration enum) { this.enum = enum; } public boolean hasNext () { return enum.hasMoreElements ( ); } public Object next ( ) { return enum.nextElement ( ); } public void remove ( ) { throw new UnsupportedOperationException ( ); } }
Since we are adapting Enumeration to Iterator, the EnumerationIterator must implement the Iterator interface -- it has to look like the Iterator. The Enumeration we are adapting. Were using composition so we stash it in an instance variable. hasNext ( ) and next () are implemented by delegating to the appropriate methods in the Enumeration. For the remove ( ) we simply throw an exception.

Question: Some AC adapters do more than just change the interface -- they add other features like surge protection, indicator lights, and other bells and whistles. If you were going to implement these kinds of features, what pattern would you use?

Summary
When you need to use an existing class and its interface is not the one you need, use an adapter. An adapter changes an interface into one a client expects. Implementing an adapter may require little work or a great deal of work depending on the size and complexity of the target interface. There are two forms of adapter patterns: object and class adapters. Class adapters require multiple inheritance. An adapter wraps an object to change its interface, a decorator wraps an object to add new behaviors and responsibilities.

You might also like