Professional Documents
Culture Documents
Adapter
Adapter
Adapter
INTENT
• Convert the interface of a class into another interface clients
expect.
• Adapter lets classes work together that couldn't otherwise
because of incompatible interfaces.
• Wrap an existing class with a new interface.
• Also Known As
-> Wrapper
slide 2
Design Patterns presentation: Adapter pattern
Winter 2010
MOTIVATION
• Sometimes a toolkit or class library can not be used because its
interface is incompatible with the interface required by an
application
• We can not change the library interface, since we may not have
its source code
• Even if we did have the source code, we probably should not
change the library for each domain-specific application
Design Patterns presentation: Adapter pattern
Winter 2010
MOTIVATION
• Example:
Design Patterns presentation: Adapter pattern
Winter 2010
PARTICIPANTS
• Target (shape)
• defines the domain-specific interface that Client uses.
• Adapter (TextShape)
• adapts the interface Adaptee to the Target interface.
• Adaptee (TextView)
• defines an existing interface that needs adapting.
• Client (DrawingEditor)
• collaborates with objects conforming to the Target interface.
Design Patterns presentation: Adapter pattern
Winter 2010
STRUCTURE
• A class adapter uses multiple inheritance to adapt one interface
to another:
Design Patterns presentation: Adapter pattern
Winter 2010
STRUCTURE
• An object adapter relies on object composition:
slide 7
Design Patterns presentation: Adapter pattern
Winter 2010
COLLABORATION
slide 8
Design Patterns presentation: Adapter pattern
Winter 2010
APPLICABILITY
Use the Adapter pattern when
• You want to use an existing class, and its interface does not
match the one you need
• You want to create a reusable class that cooperates with
unrelated classes with incompatible interfaces
slide 9
Design Patterns presentation: Adapter pattern
Winter 2010
CONSEQUENCES
• Class adapter
• Concrete Adapter class
• Unknown Adaptee subclasses might cause problem
• Overloads Adaptee behavior
• Introduces only one object
• Object adapter
• Adapter can service many different Adaptees
• May require the creation of Adaptee subclasses and referencing those
objects
slide 10
Design Patterns presentation: Adapter pattern
Winter 2010
IMPLEMENTATION
• How much adapting should be done?
• Simple interface conversion that just changes operation names and order of
arguments
• Totally different set of operations
• Does the adapter provide two-way transparency?
• A two-way adapter supports both the Target and the Adaptee interface. It allows an
adapted object (Adapter) to appear as an Adaptee object or a Target object
slide 11
Design Patterns presentation: Adapter pattern
Winter 2010
IMPLEMENTATION
• Adapter should be subtype of Target
• Pluggable adapters should use the narrowest definition
• Abstract operations to minimize exposed interface
• Delegated objects to localize behavior
• Parameterized processing avoids subclasses of adaptee
slide 12
BRIDGE PATTERN
Design Patterns presentation: Adapter pattern
Winter 2010
CONTEXT
• The normal method of dealing with an abstraction having
several implementations is through inheritance.
• However, this permanently binds the implementation to the
abstraction.
• This is not always flexible enough. You may want to modify or
extend the abstraction or implementations independently.
APPLICABILITY
• Selection or switching of implementation is at run-time rather
than design time.
• Abstraction and implementation should both be extensible by
subclassing.
• You want to isolate implementation changes from clients.
• You want to share an implementation among multiple objects
and this should be hidden from the client.
Design Patterns presentation: Adapter pattern
Winter 2010
PATTERN STRUCTURE
bridge
Design Patterns presentation: Adapter pattern
Winter 2010
A MEAL EXAMPLE
bridge
Design Patterns presentation: Adapter pattern
Winter 2010
CODE – 1 OF 1 (ABSTRACTION)
public class Meal { public class Snack extends Meal {
protected MealImp imp; public void getSnack() {
imp.getAppetizer();
public Meal() { }
imp = new AmericanMealImp(); }
}
CODE – 2 OF 2 (IMPLEMENTOR)
public interface MealImp { public class ItalianMealImp implements MealImp {
public abstract void getAppetizer(); public void getAppetizer() {
public abstract void getSoup(); System.out.println("Appetizer: anti pasti"); }
public abstract void getSalad(); public void getSoup() {}
public abstract void getFish(); public void getSalad() {}
public abstract void getMeat(); public void getFish() {}
public abstract void getPasta(); public void getMeat() {
public abstract void getCheesePlate(); System.out.println("Meat: chicken piccata"); }
public abstract void getBeverage(); public void getPasta() {}
public abstract void getDessert(); public void getCheesePlate() {}
public abstract void getSorbet(); public void getBeverage() {
public abstract void getSandwich(); System.out.println("Beverage: cappuccino"); }
} public void getDessert() {
System.out.println("Dessert: gelato"); }
public void getSorbet() {}
public void getSandwich() {}
}
public class AmericanMealImp implements MealImp {
public void getAppetizer() {
System.out.println("Appetizer: nachos"); }
public void getSoup() {}
public class FrenchMealImp implements MealImp {
public void getSalad() {}
public void getAppetizer() {
public void getFish() {}
System.out.println("Appetizer: escargot"); }
public void getMeat() {
public void getSoup() {}
System.out.println("Meat: steak"); }
public void getSalad() {}
public void getPasta() {}
public void getFish() {}
public void getCheesePlate() {}
public void getMeat() {
public void getBeverage() {
System.out.println("Meat: coq au vin"); }
System.out.println("Beverage: beer"); }
public void getPasta() {}
public void getDessert() {
public void getCheesePlate() {}
System.out.println("Dessert: apple pie"); }
public void getBeverage() {
public void getSorbet() {}
System.out.println("Beverage: bordeaux"); }
public void getSandwich() {}
public void getDessert() {
}
System.out.println("Dessert: creme brulee"); }
public void getSorbet() {}
public void getSandwich() {}
}
Design Patterns presentation: Adapter pattern
Winter 2010
CODE – 3 OF 3 (CLIENT)
public class Customer {
CODE - RESULTS
Bob@Bob-XPS ~/cspp51023/Bridge Pattern
$ java Customer American
Appetizer: nachos
Meat: steak
Beverage: beer
Dessert: apple pie
CONSEQUENCES
• Decouples interface and implementation.
• Eliminates compile-time dependencies.
• Improved extensibility.
• Hiding implementation details from client.
• Changes in the implementation of an abstraction should have
no impact on clients
Design Patterns presentation: Adapter pattern
Winter 2010
IMPLEMENTATION CONSIDERATIONS
• Only one Implementor
• Multiple implementors not always needed.
• Separation is still useful even in this degenerate case to hide implementation
changes from clients.
• Creating correct Implementor
• Instantiate in constructor based on parameters.
• Use default implementation and possibly change later.
• Use AbstractFactory.
• Sharing Implementors
• Use a reference count in the implementation to know when an instance is being
used.
Design Patterns presentation: Adapter pattern
Winter 2010
RELATED PATTERNS
Abstract Factory -
Used to create the Implementor and remove all knowledge of
which one from the Abstraction.
Adapter –
Used to make 2 unrelated classes work together. Usually
applied after system is designed. Bridge does similar work but
is done up front during design.