Chapter 3 Adapter Summary prepared by Kirk Scott
23K - views

Chapter 3 Adapter Summary prepared by Kirk Scott

1. Whimbrel. From Wikipedia, the free . encyclopedia. The . Whimbrel. (. Numenius. . phaeopus. ) is a . wader. in the large family . Scolopacidae. . It is one of the most widespread of the . curlews.

Download Presentation

Chapter 3 Adapter Summary prepared by Kirk Scott




Download Presentation - The PPT/PDF document "Chapter 3 Adapter Summary prepared by Ki..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.



Presentation on theme: "Chapter 3 Adapter Summary prepared by Kirk Scott"— Presentation transcript:

Slide1

Chapter 3Adapter

Summary prepared by Kirk Scott

1

Slide2

WhimbrelFrom Wikipedia, the free encyclopedia

The

Whimbrel

(

Numenius phaeopus) is a wader in the large family Scolopacidae. It is one of the most widespread of the curlews, breeding across much of subarctic North America, Europe and Asia as far south as Scotland.This is a migratory species wintering on coasts in Africa, South America, south Asia into Australasia and southern North America. It is also a coastal bird during migration.[2] It is fairly gregarious outside the breeding season.

2

Slide3

3

Slide4

GodwitFrom Wikipedia, the free encyclopedia

Jump to:

navigation

,

search For other uses, see Limosa (disambiguation).The godwits are a group of large, long-billed, long-legged and strongly migratory waders of the bird genus Limosa. Their long, bills allow them to probe deeply in the sand for aquatic worms and molluscs. They frequent tidal shorelines, breeding in northern climates in summer and migrating south in winter. In their winter range, they flock together where food is plentiful. A female Bar-tailed Godwit holds the record for the longest non-stop flight for a land bird.[1]4

Slide5

They can be distinguished from the

curlews by their straight or slightly upturned bills, and from the

dowitchers

by their longer legs. The winter plumages are fairly drab, but three species have reddish

underparts when breeding. The females are appreciably larger than the males.Although not common tablefare today, they were once a popular British dish. Sir Thomas Browne writing in the seventeenth century noted that godwits "were accounted the daintiest dish in England."The name Godwit originates in Old English with god meaning good, and wit coming from wihte, meaning creature.[2]5

Slide6

6

Slide7

7

Slide8

CurlewFrom Wikipedia, the free encyclopedia

Jump to:

navigation

,

search For other uses, see Curlew (disambiguation).For other uses of "Numenius", see Numenius.The curlews /ˈkɜrljuːz/, genus Numenius, are a group of eight species of birds, characterised by long, slender, downcurved bills and mottled brown plumage. They are one of the most ancient lineages of scolopacid waders, together with the godwits which look similar but have straight bills.[1] In

Europe

"curlew" usually refers to one species, the

Eurasian Curlew

Numenius

arquata

.

8

Slide9

9

Slide10

Design Patterns in JavaChapter 3

AdapterSummary prepared by Kirk Scott

10

Slide11

Introduction Before the Introduction

The adapter design pattern is fundamentalOne of my jokes is that once you’ve seen the adapter pattern, every pattern after it can be described as a kind of adapter

The pattern allows one class to “make use of” another

11

Slide12

Structurally, there are two different implementations of the pattern

The Class Adapter is based on an interface and a subclassThe Object Adapter is based on a subclass and a wrapped instance of another class

12

Slide13

Introduction to the Class Adapter

Consider these possible scenarios in the development of client and service code which need to work togetherThe client and service code may simply be written independently, without (advance) knowledge of each other’s interfaces

Or, the client code may be written before the service code

13

Slide14

Or, code bases may belong to different organizations which happen to define different interfaces for the same functionality

In any of these scenarios, the client code may make calls to methods that do not end up in the service code

14

Slide15

The ultimate goal is for the client and server to work together in spite of the mismatch

In order for this to happen, at the very least the needed functionality has to exist in the service code, even if it is behind a different interface

15

Slide16

You may consider rewriting either the client or the service code so that their naming conventions match

However, this may not be possible for political or timing reasonsEven if possible, recoding may be undesirable because it’s too much work

16

Slide17

In a situation like this, the adapter pattern can be used

By insightful use of interfaces and subclasses, adding one class to the system makes it possible for the client code base to use the service code base

17

Slide18

Book Definition of Pattern

Book definition:The intent of Adapter is to provide the interface that a client expects while using the services of a class with a different interface

18

Slide19

The Class Adapter: Adapting to an Interface

In the ideal case, client and service code are simply written to be consistent with each otherIf the client code is written first, the client developer may create an interface which defines all of the calls the client will need to make

Then the service code developer can have the service classes implement that interface

19

Slide20

In the less than ideal case, the service code is not written to the desired interface

However, such an interface, defining what the client needs, can be used to apply the class adapter design patternThe adapter class, which connects the client with the service code, will

implement this interface

20

Slide21

The adapter class

will also extend the class in the service code base which contains the useful methodsThe implementation of the interface methods in the adapter class are based on calls to the useful, but “misnamed” methods inherited from the

superclass

in the service code base

21

Slide22

The diagram on the following overhead illustrates a class adapter

Note that for this pattern a UML diagram can be given right awayThe pattern is immediately apparent from the diagram

22

Slide23

23

Slide24

The client makes use of an interface,

RequiredInterface, which specifies a method named requiredMethod

()

The service code contains a class,

ExistingClass with a method named usefulMethod(), which contains the needed functionalityThe NewClass is the adapter, which implements the interface and extends ExistingClassThe implementation of requiredMethod() in NewClass is based on calls to usefulMethod() in ExistingClass24

Slide25

Using the Class Adapter in Practice

Before moving on, there is another aspect of this to considerIn the diagram, the client is shown as making use of the interface by means of a solid line with an open arrowhead

This notation in UML can mean that the client has an instance variable of the type referred to

25

Slide26

This notation can also mean that the client has a reference to something with that type which isn’t an instance variable

For example, the client may have a parameter of that typed passed to it

26

Slide27

Interface References to Objects

Either way, the critical idea is this:The client code is written with references to the interface, not references to specific classesAn object of any class that implements the interface can be passed to the client and used by it

27

Slide28

This is a simple, but very important idea

In CSCE 222 you learn about superclass references to subclass objectsHere you are seeing interface references to objects of classes that implement the interface

Technically, there were one or two cases of this in CSCE 222, but they were sideshows at the time

28

Slide29

Implementation of Adapter Methods

The client will be written to call the method requiredMethod(), but not on a direct reference to a

NewClass

object

The client will be written to call the method requiredMethod() in this way:requiredInterfaceReference.requiredMethod()29

Slide30

A More Concrete Example

The book gives an example of a class adapter using rocketsThe example will center on two methods relevant to the performance of rockets during flight,

getMass

() and

getThrust()The mass and thrust of a rocket are dependent on timeOver the course of a flight, as fuel is burnt, mass goes down, and at some point the rocket achieves maximum thrust30

Slide31

The Structure of the Example

The example begins with two parts:EventSim, a rocket simulation program, the client

RocketSim

, the interface for rockets used by the client

A UML diagram for this is shown on the following overhead31

Slide32

32

Slide33

The example also has a

PhysicalRocket class which represents rocketsThe goal is to run EventSim

and apply it to instances of the

PhysicalRocket

classThe PhysicalRocket class methods are not exactly the same as the methods in the RocketSim interface33

Slide34

The methods in the class

PhysicalRocket parallel the functionality of the methods in the RocketSim interface

The names of the methods in the interface and the class are the same, but their parameter lists differ

The

PhysicalRocket class has to be adapted to the RocketSim interface34

Slide35

The

PhysicalRocket class is adapted to the RocketSim interface in this way:

You write a new, adapter class,

OozinozRocket

, which implements the interface and extends the class.The book does this in steps, as a challengeThe UML diagram on the following overhead cuts to the chase35

Slide36

Challenge 3.1 Solution

36

Slide37

The adapter class has to deal with the mismatch in the specifications between the adapter interface and the class to be adapted

The getMass() and

getThrust

() methods take no parameter in the

RocketSim interfaceThey take a time parameter in the PhysicalRocket class37

Slide38

There is a

setSimTime() method in the RocketSim interface

RocketSim

keeps an internal clock and occasionally updates simulated objects by calling the

setSimTime() methodThe adapter class implements this method and provides the instance variable needed for it38

Slide39

This instance variable makes it possible for the adapter to make use of the base class methods

An adapter method which doesn’t take a time parameter is implemented by calling a service class method that does take a time parameter

The adapter method passes in the time instance variable when calling the service class method

39

Slide40

The adapter class,

OoozinozRocket, inherits methods from the PhysicalRocket class

These inherited methods are used in implementing the interface methods

The following overheads show the code solution for the adapter class

As usual, the book does this as a challengeThe solution is simply presented here40

Slide41

Solution 3.2

package

com.oozinoz.firework

;

import com.oozinoz.simulation.*;public class OozinozRocket extends PhysicalRocket implements RocketSim{/*** The adapter class has this instance variable. ***/

private double time;

41

Slide42

public

OozinozRocket

(double

burnArea

, double burnRate, double fuelMass, double totalMass){ super(burnArea, burnRate

,

fuelMass

,

totalMass

);

}

/*** The adapter class also has this set method for the needed variable. ***/

public void

setSimTime

(double time)

{

this.time

= time;

}

42

Slide43

/*** With the variable available, it’s a piece of cake to implement these methods. ***/

public double

getMass

()

{ return getMass(time);}public double getThrust(){ return getThrust(time);}

43

Slide44

More Comments on the Code

The time instance variable provides the parameter needed in order to call the service class methodsIt is apparent that the client side developer, when specifying the interface, knew that a time variable would be necessary

That accounts for the inclusion of

setSimTime

() in the interface44

Slide45

Both

getMass() and getThrust() are overloaded in the Adapter class

The class inherits the versions which take parameters and implements the versions which don’t

45

Slide46

The interface versions of the methods don’t have a time parameter

The client code only calls these versionsThe service code versions of the methods do have a time parameter

In the adapter class code, a call to the service method—with a time parameter—is wrapped inside the implementation of the interface version of the method

46

Slide47

Simplicity/Complexity

The example is simpleIt’s so simple that you may overlook what is happening

When you call one version of a method, that is delegated to another version of the same method

The call is passed on, and that call is made on the implicit parameter

47

Slide48

The adapter for the client side has get methods that don’t take a time parameter

They assume that the needed time is passed in with a call to setSimTime()

The service class actually has methods that take the needed time parameter

48

Slide49

You might think if mass and thrust depend on time, then the client side code might have been written with method calls which passed time as a parameter

But setting the simulation time separately is an equally valid way of making the time available

49

Slide50

If time is made available in this way, then in the client code:

You would have to pay careful attention to when you had called setSimTime() before calling either

getMass

() or

getThrust()The return values of the get calls will depend on the most recent value of simTime that was sent in50

Slide51

Introduction to the Object Adapter

Suppose that the client code base does not specify a particular interfaceInstead, it has been coded to use the methods of a particular class

Suppose that a different class exists in the service code which provides the necessary functionality

51

Slide52

An object adapter is a class which extends the class specified in the client and wraps an instance of the service class

The adapter derives the needed functionality from the wrapped instanceIn other words, the methods in the adapter class work by calling methods on the wrapped object

52

Slide53

This way of doing things is expressed by the term “delegation”

The object adapter delegates responsibility for the actual functionality desired to the instance of the service class it containsThe adapter class adapts an instance of the service class for use by the client by providing an appropriate interface for it

53

Slide54

The diagram on the following overhead illustrates an object adapter

Note that for this pattern, just like for a class adapter, a UML diagram can be given right awayThe pattern is immediately apparent from the diagram

54

Slide55

55

Slide56

The adapter class is connected to the useful class by means of a navigability arrow

The adapter class contains a reference to a useful class instance variableThe adapter class implements the interface needed by the client

It does so by making calls to methods on the useful object

56

Slide57

The form of delegation in the adapter class is illustrated by this snippet of code:

requiredMethod

()

{

… existingClassObjectReference.usefulMethod(); …} 57

Slide58

The structures of the class and object adapters are not the same

However, both are valid adaptersTheir intent and functional effect are the same

58

Slide59

A More Concrete Example

Suppose that the EventSim client is coded to work directly with references to objects of a class named Skyrocket

The Skyrocket class has methods

getMass

(), getThrust() which do not take a time parameterIt also has a setSimTime() methodThe UML diagram shown on the following overhead illustrates this idea59

Slide60

UML for the Client Side

60

Slide61

The Service Side of the Example

The service side of the application is similar to the previous scenarioThere is a PhysicalRocket

class that implements the desired functionality

You want to use the methods of the

PhysicalRocket class to support the functionality of the methods of the Skyrocket class on the client side61

Slide62

The Adapter Class

The adapter class will be a subclass of the client side SkyRocket classThe adapter class will have a

PhysicalRocket

instance variable

The adapter class will override the methods, delegating to the PhysicalRocket it contains62

Slide63

As usual, the book does things in stages

The UML diagram given on the next overhead shows the book’s complete design

63

Slide64

Solution 3.4

64

Slide65

Things to Note in the Diagram

You might note that if there were such a thing, multiple inheritance would be an approach to solving the problemIn the class adapter you implement an interface on the client side and extend a class on the service side

Here, you extend a class on the client side

You can’t also extend the class on the service side

Instead, you have to wrap an instance65

Slide66

The simulation time variable, as in the class adapter example, is at the heart of what you will have to do in your implementation

In the SkyRocket class there is a double instance variable

simTime

and a

setSimTime() methodIn this example these are inherited by the adapter subclass66

Slide67

The

simTime variable is marked with a # sign, meaning that it’s declared protectedThat means that the adapter subclass will have direct access to its own

simTime

instance variable without calling a get method

This is not a design decision that I would preferIt will be discussed further later on67

Slide68

Code for the Object Adapter Example

The object adapter class has to obtain a reference to a PhysicalRocket object

The object adapter class also has to override

getMass

() and getThrust()The book’s code is presented on the following overheads with commentary68

Slide69

The beginning of the OozinozSkyrocket class code.

package

com.oozinoz.firework

;

import com.oozinoz.simulation.*;public class OozinozSkyrocket extends Skyrocket{ private PhysicalRocket rocket;

69

Slide70

The book’s constructor for the subclass, which relies on an instance of the PhysicalRocket class being passed in

public

OozinozSkyrocket

(

PhysicalRocket r){ super(r.getMass(0); r.getThrust(0); r.getBurnTime()); rocket = r;

}

70

Slide71

The constructor for the object adapter relies on a call to super in the

superclass on the client side, SkyrocketThe

superclass

constructor requires values for mass and thrust

This is the first example of wrappingThe needed values are acquired by calling getMass() and getThrust() on the input parameter, the PhysicalRocketBecause this is initialization, time t = 0 is usedThe call to super has to come firstThen you can initialize the instance variable, r71

Slide72

An Alternative Approach

You could also write the constructor for the subclass to take in the construction parameters for a PhysicalRocket

object

Then the

OozinozSkyrocket constructor would construct an instance of PhysicalRocket instead of receiving one as a parameterThis is not better, just an alternativeOne way or the other, the instance of the object adapter class, OozinozSkyrocket, has to end up with a live PhysicalRocket reference inside it72

Slide73

Using the Object Adapter in Practice

The Object Adapter pattern works because of straightforward polymorphismYou can have a

superclass

reference to a subclass object

In the client code, a parameter would be typed to the superclass, Skyrocket, for exampleA reference to the adapter subclass, OozinozSkyrocket, could then be passed to the client code73

Slide74

The method implementations in the OozinozSkyrocket

object adapter class code

public double

getMass

(){ return rocket.getMass(simTime);}public double getThrust(){ return

rocket.getThrust

(

simTime

);

}

74

Slide75

Compare the foregoing with the solution in the Class Adapter case:

public double

getMass

()

{ return getMass(time);}public double getThrust(){ return getThrust(time);}

75

Slide76

In the Class Adapter case you call methods inherited from the

PhysicalRocket class on the implicit parameter in order to implement the adapter methodsIn the Object Adapter case, you call methods on an instance of the

PhysicalRocket

class in order to implement the adapter methods

In both cases the conversion is from a method that takes a time parameter to one that doesn’t76

Slide77

Challenge 3.4

“Name one reason why the object adapter design that the OozinozSkyrocket class uses may be more fragile than a class adapter approach.”

77

Slide78

Solution 3.4

“The object adapter design that the OozinozSkyrocket class uses may be more fragile than a class adapter approach for the following reasons.

[see the following overheads]

78

Slide79

[1] There is no specification of the interface that the

OozinozSkyrocket class provides.

As a result, the Skyrocket might change in ways that would create problems at runtime but go undetected at compile time.

[Comments will follow.]

79

Slide80

[2] The

OozinozSkyrocket counts on being able to access the simTime variable of its parent class, although there is no guarantee that this variable will always be declared as protected and no guarantee about the meaning of this field in the Skyrocket class.

(We don’t expect the providers to go out of their way to change the Skyrocket code we rely on, but on the other hand, we have limited control over what they do.)”

80

Slide81

Comments on Fragility Number 2

Comment mode on:I want to deal with “fragility” number 2 first:This is the kind of nonsense that makes you want to bellow in revulsion and disbelief

The instance variable should be declared private, not protected

This has nothing to do with the design pattern, and the fact that they identify this as a shortcoming is merely an argument against their own lame coding practices

81

Slide82

Comments on Fragility Number 1

Regarding “fragility” number 1, the premise seems to be the following:In the class adapter pattern, you specify the desired interface

Presumably, having made the specification, it is something that is unlikely to change

82

Slide83

The authors assume that the specifications of the Skyrocket class may be subject to change

On the one hand, you might ask whether this is more changeable than an interfaceAt any rate, they then observe that the changes might cause problems that the compiler wouldn’t catch and which would only be evident at run time

83

Slide84

How might this happen?

The superclass has its instance variables and methods changed

The subclass inherits all of the changes, but—

It still includes the methods developed earlier

These methods may still override methods in the superclassIf the superclass methods are gone, then the methods in the subclass are simply independent84

Slide85

The bottom line is that the set of methods in the subclass may no longer appropriately perform adaptation

The fundamental moral of the story is this:If you develop a hierarchy of classes and you make a change in a

superclass

, you need to trace down through all of its subclasses to see whether or not they are still OK

85

Slide86

This fundamental design and coding principle applies whether you’re talking about adapters or not

If you can safely assume that a specified interface is unlikely to change, then the class adapter pattern is not liable to this problem

On the other hand, if the interface specification does change, you face a similar situation

86

Slide87

You would have to look at every class that implemented the interface to make sure that the implementation matched the new specification

The difference is that the compiler would detect classes that declared that they implemented the interface but which no longer conformed to the interface specifications

87

Slide88

Final Methods and Adaptation

The book makes another observation about the applicability of the object adapterIf one of the methods in the client

superclass

had been declared final it couldn’t be overridden in a subclass

Then the the object adapter approach wouldn’t workThere are always potential problemsDirty Harry says, “Know your limitations.”88

Slide89

Choosing between Class and Object Adapters

The book suggests that the class adapter is preferable to the object adapterHowever, you do what you have to do

If no client interface is given, the object adapter approach works

89

Slide90

Are Java Adapter Classes the Same as the Adapter Design Pattern?

The answer to this question is basically “no”It is just a coincidence that the term adapter has been applied in both situations

90

Slide91

The End

91

Slide92

Slide93