adapter pattern · 2017. 9. 28. · adapter pattern solution solution: build a wrapper class....

19
Adapter Pattern Or building a wrapper class

Upload: others

Post on 24-Sep-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Adapter Pattern

Or building a wrapper class

Page 2: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Adapter Purpose

Purpose: Create a wrapper around an existing class that you don’t control. The wrapper makes the object conform to your needs.

Problem (or When to Use): Have a class that almost does what I need.

Has all (or almost) the right behavior, but has wrong access methods.

Page 3: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Adapter Pattern Solution

Solution: Build a wrapper class.

Implementation: Build a wrapper class around the existing class. Use your class instead.

Consequences: Allows pre-existing classes to be used in your code. Will not work if existing class is missing some key behavior.

Page 4: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

So What’s a Wrapper?

A class that encompasses another class (or method, or…)

We’ve seen examples with the composition notation.

Why would this indicate that one class wraps around another?

WoodPlankBarn

Page 5: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Java Example: Integer

Example : The Integer class in Java. This class wraps itself around the “int”

datatype. So not quite like composition, but close.

Why did Java developers want to do this? int does everything they want, except cannot be

treated as an object.

Solution: Integer class wraps int, and now extends Object class. So the Integer has the int and is an Object.

Object Integer

Page 6: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Java Example: Integer (cont.)

What’s the advantage of this wrapper? Some methods can require an Object as a parameter.

e.g., void toString(Object o)

e.g., boolean equals(Object o)

(actually a method in the Object class)

Can accept almost anything!

But can’t accept an int (or char, or float, or double, or boolean).

Problem: can’t pass int as an Object. Solution: build wrapper called Integer.

This is an adapter class!

Page 7: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Java Example: Integer (cont.)

What would the code look like? (pseudo…)

public class Integer

{

private int i; //creates an int inside this class.

//This is what we are wrapping around!

public Integer(int iValue)

{

i = iValue; //sets the int’s value when instantiated

}

public int getInteger() //actually called intValue()

{

return i;

}

public String toString()

{

return “”+i;

}

}

Page 8: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Java Example: Integer (cont.)

So now when a method requires an Object, we can pass it the integer rather than the int.

toString(3) //ERROR

toString(Integer(3)) //Ahhhhh… wrapped!

Page 9: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Another Example: EmailSender

S’pose I am asked to write an email sender.

Suppose project already has an existing class SpamSender()

existing class has methods for

sendSpam

setSubject

setBody

Suppose that the sendSpamTo must be given multiple addresses

Page 10: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Another Example (cont.)

1. I’d prefer my code was written with a method called sendEmail() rather than sendSpam()

2. My code only provides one email address.

3. sendSpam() returns the # of bad email addresses, but I don’t care about that.

4. But, I don’t want to rewrite everything!

Solution: A wrapper – Adapter pattern Why not solve with a Façade? Because we are

changing the behavior, not just hiding existing behaviors.

Page 11: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Another Example (cont.)

public class EmailSender

{

private EmailAddress fakeAddress = new EmailAddress([email protected]);

private SpamSender spam;

public EmailSender()

{

spam = new SpamSender(); //creates a SpamSender inside this class.

} //This is what we are wrapping around!

public void sendEmail(EmailAddress sendToRealAddress)

{

spam.sendSpam(sendToRealAddress, fakeAddress);

}

}

I don’t have two addresses, so I just give it a fake one.

Page 12: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Another Example (cont.)

So what’s the UML picture?

EmailSender

+sendEmail(:EmailAddress):void

SpamSender

+sendSpam(:EmailAddress, :EmailAddress):int

1

1

Page 13: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Another Example (cont.)

Collaboration diagram

:Driver

:EmailSender

:SpamSender

1: sendEmail(:EmailAddress) : void

1.1: sendSpam(:EmailAddress, :EmailAddress) : int

Page 14: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Adapter Pattern UML

UML diagram:

AdapteeAdapter Now can use Adapter in place of Adaptee.

Page 15: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Adapter Pattern UML May Vary

As I’ll say many times, design patterns may be (slightly) altered to fit your needs.

They’re just patterns.

Consider the following: Before the Adapter Pattern…

Client ExistingClass

+methodCall()

Adaptee

+adapteeCall()

Almost does what we want, but not quite.

Page 16: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Adapter Pattern UML Option 2

Common alteration of Adapter:

Client ExistingClass

+methodCall()

AdapteeAdapter

+methodCall() +adapteeCall()

Use this when Client, ExistingClass, and Adaptee already exist. Adapter takes the interface of Adaptee and makes it work with the ExistingClass. So client calls “methodCall” and gets behavior of “adapteeCall”.

What’s the advantage of this approach? The Client class never even knows that the wrapper class exists. Taking advantage of polymorphism! Same method call, different behavior because deals with Adaptee.

Page 17: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

Adapter UML: Why Not Inheritance?

Well, it might be, (as above UML shows) but not usually.

We want to adapt something to our own purposes and “hide” the old inappropriate version.

For example, we want to hide the SpamSender and replace it with an EmailSender.

Inheritance will extend existing code, but may not hide the old code.

If EmailSender inherits from the SpamSender, then the interface will include the inherited method sendSpam. Aurgh! We wanted to get rid of that, or hide it.

We could override the sendSpam, but then we have an interface with a misleading method name (“sendSpam”) that doesn’t sound anything like “sendEmail”.

Better option: Use composition to completely hide the old code.

Page 18: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

How Different From Façade?

Very similar – dealing with an interface to pre-existing classes.

Adapter provides an interface without simplifying. Adds new features or a new way to access old features. polymorphism likely composition likely (almost always) aggregation not likely

Façade provides simplified interface. Never adds new features. polymorphism less likely composition likely aggregation also likely

Sometimes, the adaptation might appear to simplify. In those cases, you are creating both an adapter and a façade.

Page 19: Adapter Pattern · 2017. 9. 28. · Adapter Pattern Solution Solution: Build a wrapper class. Implementation: Build a wrapper class around the existing class. Use your class instead

OK, Your Turn

Create 2 teams.

Each team must adapt the Java LinkedList API to be a Stack.

In other words, turn the existing linked list into a stack.

If unclear, justify why it is not just the façade pattern.

If stuck, consider other team’s answer.