Adapter

You might also like

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 24

ADAPTER PATTERN

Design Patterns presentation: Adapter pattern


Winter 2010

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.

• The Bridge Pattern decouples an abstraction from its


implementation.
Design Patterns presentation: Adapter pattern
Winter 2010

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(); }
}

public Meal(String type) {


if (type.equals("American")) public class Lunch extends Meal {
imp = new AmericanMealImp(); public void getLunch() {
if (type.equals("Italian")) imp.getSandwich();
imp = new ItalianMealImp(); imp.getBeverage();
if (type.equals("French")) }
imp = new FrenchMealImp(); }
}

public void getFirstCourse() { public class FiveCourseMeal extends Meal {


imp.getAppetizer(); public void getEnormousDinner() {
} imp.getAppetizer();
imp.getSorbet();
public void getSecondCourse() { imp.getSoup();
imp.getMeat(); imp.getSorbet();
} imp.getSalad();
imp.getSorbet();
public void getBeverage() { imp.getFish();
imp.getBeverage(); imp.getSorbet();
} imp.getMeat();
imp.getSorbet();
public void getDessert() { imp.getCheesePlate();
imp.getDessert(); imp.getDessert();
} imp.getBeverage();
} }
}
Design Patterns presentation: Adapter pattern
Winter 2010

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 {

private Meal meal;

public Customer(Meal aMeal) { meal = aMeal; }

public void eat() {


meal.getFirstCourse();
meal.getSecondCourse();
meal.getBeverage();
meal.getDessert();
}

public static void main(String[] args) {


Meal aMeal = null;

// Read the input to see if we do American, Italian or French


if (args.length == 0) {
// create default Meal
aMeal = new Meal();
}
else if (args.length == 1) {
// see if arg is NOT American, Italian or French
if (!(args[0].equals("American")) && !(args[0].equals("Italian")) && !(args[0].equals("French"))) {
System.err.println("1 arg given but not recognized");
System.err.println("usage: java Customer [American|Italian|French]");
System.exit(1);
}
else {
aMeal = new Meal(args[0]);
}
}
else { // error
System.err.println("wrong number of args");
System.err.println("usage: java Customer [American|Italian|French]");
System.exit(1);
}

Customer c = new Customer(aMeal);


c.eat();
}
}
Design Patterns presentation: Adapter pattern
Winter 2010

CODE - RESULTS
Bob@Bob-XPS ~/cspp51023/Bridge Pattern
$ java Customer American
Appetizer: nachos
Meat: steak
Beverage: beer
Dessert: apple pie

Bob@Bob-XPS ~/cspp51023/Bridge Pattern


$ java Customer Italian
Appetizer: anti pasti
Meat: chicken piccata
Beverage: cappuccino
Dessert: gelato

Bob@Bob-XPS ~/cspp51023/Bridge Pattern


$ java Customer French
Appetizer: escargot
Meat: coq au vin
Beverage: bordeaux
Dessert: creme brulee

Bob@Bob-XPS ~/cspp51023/Bridge Pattern


$
Design Patterns presentation: Adapter pattern
Winter 2010

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.

You might also like