0% found this document useful (0 votes)
35 views

Adapter Design Patterns

The document discusses the adapter design pattern. The adapter pattern allows classes with incompatible interfaces to work together by converting the interface of one class into another interface that clients expect. The document provides an example of using an adapter class to allow a client that expects an "EnemyAttacker" interface to work with an "EnemyRobot" class that has a different interface. It involves creating an EnemyAttacker interface, an EnemyTank class that implements the interface, an EnemyRobot adaptee class, and an adapter class that implements EnemyAttacker and delegates to EnemyRobot. The adapter pattern lets classes work together that otherwise couldn't because of incompatible interfaces.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views

Adapter Design Patterns

The document discusses the adapter design pattern. The adapter pattern allows classes with incompatible interfaces to work together by converting the interface of one class into another interface that clients expect. The document provides an example of using an adapter class to allow a client that expects an "EnemyAttacker" interface to work with an "EnemyRobot" class that has a different interface. It involves creating an EnemyAttacker interface, an EnemyTank class that implements the interface, an EnemyRobot adaptee class, and an adapter class that implements EnemyAttacker and delegates to EnemyRobot. The adapter pattern lets classes work together that otherwise couldn't because of incompatible interfaces.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

Adapter Design Patterns

Lecture 21
Adapter Design Pattern
 Gang of Four state the intent of Adapter is to
 Convert the interface of a class into another interface that
the clients expect. Adapter lets classes work together that
could not otherwise because of incompatible interfaces.
Problem Specification:
Step 1:
 You are given the following class library to draw
shapes.
Shape

+display()
+fill()
+undisplay()

Line Square

+display() +display()
+fill() +fill()
+undisplay() +undisplay()
Step 2:

 Now you are asked to add another class to deal


with circle. Your plan was:
Shape

+display()
+fill()
+undisplay()

Circle
Line Square

+display() +display()
+fill() +display()
+fill() +fill()
+undisplay() +undisplay() +undisplay()
Step 3:
 Then your client said: “No,no,no”. You have to use this
nice class library for drawing circles. Unfortunately, it is
from a different vendor and it has a different interface.
Shape

+display()
+fill()
AnotherCircle
+undisplay()

+setLocation()
+drawIt()
+fillIt()
+setItColor()
Line Square +unDrawIt()
+display() +display()
+fill() +fill()
+undisplay() +undisplay()
Adapter Design Pattern
 Problem: An "off the shelf" component offers
compelling functionality that you would like to reuse,
but its "view of the world" is not compatible with the
philosophy and architecture of the new system
 Adapter is about creating an intermediary abstraction
that translates, or maps, the old component to the new
system
 Use Adapter when you need a way to create a new
interface for an object that does the right stuff but has
the wrong interface
Two kinds of adapter pattern

 Object adapter pattern


The adapter class contains adaptee object
 Class adapter pattern
Adapter class is inherited from both adaptee and
abstract class.
Object Adapter

AbstractClass

AdapterClass AdapteeClass
Adapter Design Pattern Solution
Object Adapter
Shape

+display()
adaptee
+fill()
+undisplay()

AnotherCircle
Line Circle
Square

+display() -aCircle:AnotherCircle +setLocation()


+display()
+fill() +drawIt()
+fill() +display()
+undisplay() +fillIt()
+undisplay() +fill() +setItColor()
+undisplay() +unDrawIt()

void display(){ void fill(){ void undisplay(){


aCircle.drawIt(); aCircle.fillIt(); aCircle.unDrawIt();
} } }
Class Adapter

AbstractClass AdapteeClass

AdapterClass
Adapter Design Pattern Solution
Class Adapter
AnotherCircle

Shape
+setLocation()
+drawIt()
+display() +fillIt()
+fill() +setItColor()
+undisplay() +unDrawIt()

Line Square Circle

+display() +display()
+fill() +fill() +display()
+undisplay() +undisplay() +fill()
+undisplay()

void display(){ void fill(){ void undisplay(){


drawIt(); fillIt(); unDrawIt();
} } }
Class Adapter Vs Object Adapter

 Class Adapter
 uses inheritance and can only wrap a class. It cannot
wrap an interface since by definition it must derive
from some base class.

 Object Adapter
 uses composition and can wrap classes or interfaces, or
both. It can do this since it contains, as a private,
encapsulated member, the class or interface object
instance it wraps.
Goal of Adapter Pattern

 Keeping the client code intact we need to write a


new class which will make use of services offered
by the class.

 Convert the services offered by class to the client


in such a way that functionality will not be
changed and the class will become reusable.
Flow of Events in Adapter
Pattern
 Client call operations on Adaptor instance, which
in return call adaptee opertions that carry out the
request.
 To use an adapter:
 The client makes a request to the adapter by calling a method on it
using the target interface.
 The adapter translates that request on the adaptee using the adaptee
interface.
 Client receive the results of the call and is unaware of adapter’s
presence.
Implementation steps

 Identify the desired interface.


 Design a "wrapper" class that can "impedance
match" the old to the new.
 The adapter/wrapper class "has a" instance of the
legacy class.
 The adapter/wrapper class "maps" (or delegates)
to the legacy object.
 The client uses (is coupled to) the new interface.
Components of Adapter Class
1. Adaptee: Defines an existing interface that needs
adapting; it represents the component with which the
client wants to interact with.
2. Target: Defines the domain-specific interface that the
client uses; it basically represents the interface of the
adapter that helps the client interact with the adaptee.
3. Adapter: Adapts the interface Adaptee to the Target
interface; in other words, it implements the Target
interface, defined above and connects the adaptee, with
the client, using the target interface implementation
4. Client: The main client that wants to get the operation, is
done from the Adaptee.
Limitations of Adapter Design
Pattern
 Due to adapter class the changes are encapsulated
within it and client is decoupled from the changes
in the class.
 A client in video game wants to use an enemy
attacker. Any enemy attacker can fire a weapon,
drive forward and assign driver to it. However,
you want to create an artificially intelligent enemy
robot. Now, an enemy robot has no need for a
driver and also it is not going to drive forward ,it’s
going to walk forward, and has no weapons it just
smashes things with its feet's and its hand. We
want to see enemy robot as an enemy attacker.
Step 1:Create interface for
Enemy Attacker
// This is the Target Interface : This is what the client
// expects to work with. It is the adapters job to make new
// classes compatible with this one.

public interface EnemyAttacker {

public void fireWeapon();

public void driveForward();

public void assignDriver(String driverName);

}
Step 2:
// EnemyTank implements EnemyAttacker perfectly
// Our job is to make classes with different methods
// from EnemyAttacker to work with the EnemyAttacker interface
import java.util.Random;
public class EnemyTank implements EnemyAttacker{
Random generator = new Random();
public void fireWeapon() {
int attackDamage = generator.nextInt(10) + 1;
System.out.println("Enemy Tank Does " + attackDamage + " Damage");}
public void driveForward() {
int movement = generator.nextInt(5) + 1;
System.out.println("Enemy Tank moves " + movement + " spaces");}
public void assignDriver(String driverName) {
System.out.println(driverName + " is driving the tank"); }

}
Step 3: Adaptee
// This is the Adaptee. The Adapter sends method calls
// to objects that use the EnemyAttacker interface
// to the right methods defined in EnemyRobot
import java.util.Random;
public class EnemyRobot{
Random generator = new Random();
public void smashWithHands() {
int attackDamage = generator.nextInt(10) + 1;
System.out.println("Enemy Robot Causes " + attackDamage + " Damage
With Its Hands"); }
public void walkForward() {
int movement = generator.nextInt(5) + 1;
System.out.println("Enemy Robot Walks Forward " + movement + "
spaces"); }
public void reactToHuman(String driverName) {
System.out.println("Enemy Robot Tramps on " + driverName);

}
Step 4:Adapter
// The Adapter must provide an alternative action for
// the the methods that need to be used because
// EnemyAttacker was implemented.

// This adapter does this by containing an object


// of the same type as the Adaptee (EnemyRobot)
// All calls to EnemyAttacker methods are sent
// instead to methods used by EnemyRobot

public class EnemyRobotAdapter implements EnemyAttacker{


EnemyRobot theRobot;
public EnemyRobotAdapter(EnemyRobot newRobot){
theRobot = newRobot; }
public void fireWeapon() {
theRobot.smashWithHands(); }
public void driveForward() {
theRobot.walkForward(); }
Step 4:Adapter
public void assignDriver(String driverName) {

theRobot.reactToHuman(driverName);

}
Step 5: Client
public class TestEnemyAttackers{
public static void main(String[] args){
EnemyTank rx7Tank = new EnemyTank();
EnemyRobot fredTheRobot = new EnemyRobot();
EnemyAttacker robotAdapter = new EnemyRobotAdapter(fredTheRobot);
System.out.println("The Robot");
fredTheRobot.reactToHuman("Paul");
fredTheRobot.walkForward();
fredTheRobot.smashWithHands();
System.out.println();
System.out.println("The Enemy Tank");
rx7Tank.assignDriver("Frank");
rx7Tank.driveForward();
rx7Tank.fireWeapon();
System.out.println();
Step 5: Client
System.out.println("The Robot with Adapter");
robotAdapter.assignDriver("Mark");
robotAdapter.driveForward();
robotAdapter.fireWeapon();

}
Output

You might also like