unit 10 adapter n.
Skip this Video
Download Presentation
Unit 10 Adapter

Loading in 2 Seconds...

play fullscreen
1 / 109

Unit 10 Adapter - PowerPoint PPT Presentation

  • Uploaded on

Unit 10 Adapter. Summary prepared by Kirk Scott. Design Patterns in Java Chapter 3 Adapter. Summary prepared by Kirk Scott. Adapter, Terminology and Statement of Pattern Intent.

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
Download Presentation

PowerPoint Slideshow about 'Unit 10 Adapter' - ramya

Download Now An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
unit 10 adapter

Unit 10Adapter

Summary prepared by Kirk Scott

design patterns in java chapter 3 adapter

Design Patterns in JavaChapter 3Adapter

Summary prepared by Kirk Scott

adapter terminology and statement of pattern intent
Adapter, Terminology and Statement of Pattern Intent
  • One code base is a client if it needs to make use of the functionality of methods in another code base, which would be the service provider
  • Observe the possible sequence of events in large scale or disjointed development:
  • The client code is written before the service code, and the client makes calls to methods that do not end up in the service code base specifications and implementation
adapter terminology and statement of pattern intent cont d
Adapter, Terminology and Statement of Pattern Intent, cont’d.
  • Client and service code may also simply be written independently, without (advance) knowledge of each other’s interfaces
  • Or, the specifications for the code bases belong to different organizations and the differences between their interfaces are simply set in stone or fixed for other reasons
  • Whatever the reason, the scenario is that the service code contains useful functionality, and the underlying problem is that the client code was written to call methods by names that don’t exist in the service code

This may sound like a screw-up and the the ideal solution might seem to be rewriting one or the other of the code bases so that the method names agree

  • However, if the specifications of the service code base have been set, recoding isn’t an option
  • Alternatively, once the code exists, recoding everything so that it agrees may be undesirable because it is too much work

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

  • The basic idea is that 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

There are actually several adapter scenarios

  • The simplest case is when the client code developer planned in advance for adaptation by implementing a Java interface of the necessary methods
  • There are other scenarios which fulfill the intent of adaptation but are somewhat different due to the absence of a Java interface or for other reasons
adapter terminology and statement of pattern intent1
Adapter, Terminology and Statement of Pattern Intent
  • Statement of Intent:
  • The intent of Adapter is to provide the interface that a client expects while using the services of a class with a different interface
adapting to an interface
Adapting to an Interface
  • In the ideal case, the client developer realizes that services may eventually be required from another code base
  • The client developer then creates a Java interface which includes all of the methods which the client code calls

An Adapter class implements this interface

  • The Adapter class also extends the class in the service code base which contains the useful methods
  • The 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

Concretely, the client makes use of an interface, RequiredInterface, which specifies the use of a method named requiredMethod()

  • The service code base contains an ExistingClass with a method named usefulMethod() which contains the needed functionality
  • The NewClass is an adapter which implements the interface and extends ExistingClass
  • In NewClass, the implementation of requiredMethod() is based on calls to usefulMethod()

Before moving on, there is another aspect of this to consider

  • Apparently the book considers it obvious, but when reading the book, the question arose in my mind
  • In the diagram, the client is shown as making use of the interface by means of a line with an open arrowhead

What does it mean for the client to make use of the interface?

  • Typically, you might think that the client code would contain calls of this sort: newClassObject.requiredMethod()
  • But this can’t be the case
  • The scenario is that the client doesn’t know about the contents of the service code base, and by definition, it would have been written before the adapter class was written

How does the client “know” to use an object that conforms to the interface, or how does it acquire an object of a class that implements the interface?

  • Clearly, the client code cannot be rewritten to use objects of class NewClass
  • There are two parts to the answer to this question

The first part of the answer is that although not explicitly shown, part of the use of the client consists of passing in references to objects

  • A reference to an object of NewClass could be passed into a method of the client code base
  • How can this be, if the client code does not “know about” NewClass?
  • Read on

A second part of the answer is that the input parameter to a method of the client could be typed to the interface, not to a particular class

  • This is an approach that didn’t come up in CS 202, but it will recur in this book
  • Part of the power of interfaces is that they can be used as types

If the client developer figured out the interface, then the client code can have objects and parameters typed to that interface wherever needed

  • Then truly, all that’s required for successful adaption is the creation of an adapter class that implements the interface
  • Wherever that interface is needed, references to the adapter class can be used
a more concrete example
A More Concrete Example
  • The book next explains more by working with specific example code
  • Oozinoz makes rockets, and in its code base is a class named EventSim, which runs simulations of rocket performance
  • The code base also includes the specifications for an interface, RocketSim, which represents rockets/rocket characteristics
  • EventSim was written to make use of the RocketSim interface
  • This is shown in the following UML diagram

The foregoing description and diagram represent the client side of an illustration of the Adapter class

  • In addition, Oozinoz has a PhysicalRocket class which represents rockets
  • The PhysicalRocket class has a set of methods which are useful, and more or less analogous to the methods in the RocketSim interface
  • Unfortunately, they do not have the same names

Suppose you would like to run EventSim and apply it to instances of the PhysicalRocket class

  • You can’t, but the situation is ripe for solution using the Adapter design pattern
  • The following UML diagram illustrates creating a new class, OozinozRocket, which implements the RocketSim interface and extends the PhysicalRocket class

Notice that the methods on the client and server sides don’t agree exactly in name or other characteristics

  • Frequently there isn’t a simple one-to-one correspondence between methods with exactly the same function but different names
  • In this respect, the example is relatively realistic
  • Things are rarely rock bottom simple and the adapter will have to deal with the mismatch

A brief overview reveals:

  • There are getMass() and getThrust() methods in both the interface and the class
  • However, these methods take a time parameter in the class methods and take no parameter in the interface

There is also a setSimTime() method in the interface

  • It takes a time parameter
  • Recall that when implementing an interface, it is up to the programmer to supply any needed variables
  • They are not specified in the interface
  • This suggests that some sort of time variable will be lurking somewhere in the interface implementation

There is also a getBurnTime() method in the server side class

  • It is not immediately apparent how this might be used to implement the interface methods in the Adapter class
  • On the other hand, it does seem like a potential source for the value of the time parameter

Overall, domain knowledge (an explanation by the authors of how the simulation works) is needed in order to sort out the implementation of the Adapter class

  • The authors add that RocketSim keeps an internal clock (typical of event simulators) and occasionally updates simulated objects by calling the setSimTime() method

When implementing the OozinozRocket Adapter class, it will be necessary to maintain a time instance variable which can be passed as a parameter to the PhysicalRocket class methods as needed

  • Although this really hardly seems like enough background information, the author now presents challenge 3.1
  • As usual, lack of information is no problem—we’re just going to look immediately at the provided solution anyway and try to figure it out

Challenge 3.1

  • Complete the class diagram in Figure 3.3 to show the design of an OozinozRocket class that lets a PhysicalRocket object participate in a simulation as a RocketSim object. Assume that you can’t alter either RocketSim or Physical Rocket.
  • Note that although in a sense the warning “Thou shalt not alter” should go without saying, it is a useful reminder of the reality that the Adapter pattern is intended to address.

There are no surprises in the diagram shown

  • We were warned that a time variable would be needed
  • Also, all methods of the interface are shown in the Adapter class—as they should be
  • The only potentially unexpected thing is the inclusion of a constructor specification in the Adapter class
  • However, this also doesn’t contain surprises
  • It exactly parallels the constructor in the superclass

The devil, then, is in the code writing

  • In other words, you know what methods you need to include; how do you write them?
  • Once again, domain knowledge will probably be necessary
  • In the simplest of all possible cases, it might be possible to wrap a call to a class method inside the body of an interface method

On the other hand, it may also be necessary to write more complex implementations of the interface methods in order to make successful use of the functionality in the class methods

  • The authors next give partial code for the Adapter class, leaving the implementations of two of the methods as challenges

package com.oozinoz.firework;

  • import com.oozinoz.simulation.*;
  • public class OozinozRocket
  • extends PhysicalRocket
  • implements RocketSim
  • {
  • private double time;

public OozinozRocket

  • (double burnArea, double burnRate,
  • double fuelMass, double totalMass)
  • {
  • super(burnArea, burnRate,
  • fuelMass, totalMass);
  • }

public double getMass()

  • {
  • // Challenge!
  • }
  • public double getThrust()
  • {
  • // Challenge!
  • }
  • public void setSimTime(double time)
  • {
  • this.time = time;
  • }
  • Note the use of this.time = time
  • This is an evil aberration from all that’s right and good and true…

Challenge 3.2

  • Complete the code for the OozinozRocket class, including methods getMass() and getThrust().

Before looking at the solution, consider these two observations

  • 1. Obviously you don’t have to implement getBurnTime()
  • It’s a method in the class, not the interface, and it’s inherited
  • It also turns out that it plays no role in the implementation of the interface methods

2. The solution turns out to be deceptively simple

  • Although the worst-case scenario is that the client developer has no advance knowledge, it seems that in this case the client developer knew or foresaw something about the service code base
  • The interface includes the setSimTime() method

Formally, there is no indication in the specifications of the getMass() and getThrust() methods of the interface that a simulation time would be needed in order to implement those methods

  • However, if you look at the PhysicalRocket class and see that the analogous methods require a time parameter, then it becomes necessary to support a time variable in the interface and provide a method for setting its value
solution 3 2
Solution 3.2
  • public double getMass()
  • {
  • return getMass(time);
  • }
  • public double getThrust()
  • {
  • return getThrust(time);
  • }

Just to state the obvious, 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
  • The example ultimately turns out to be an example of the simplest kind, once you understand the treatment of the time variable

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

  • The server code versions of the methods do have a time parameter
  • In the adapter code, a call to the client method is wrapped inside the implementation of the adapter version of the method
class and object adapters
Class and Object Adapters
  • The approach illustrated previously is know more specifically as a class adapter
  • This is the case where you implement a client interface and extend a service class
  • A different approach has to be taken if the client code base does not specify a particular interface
  • In this second case it’s necessary to create what is known as an object adapter

When implementing an object adapter, the idea is that rather than a Java interface in the client code, there is a class with a set of methods that need to be supported

  • The object adapter approach is to make a subclass of the client code class and then make use of an object of the service code base to help implement the methods of the subclass
  • Take a look at the following UML diagram

The book describes the object adapter, the NewClass, as adapting by means of delegation

  • Observe that NewClass is connected to ExistingClass by means of a navigability arrow
  • This means that NewClass has a reference to an object of ExistingClass and can call ExistingClass methods on that object as part of the code implementing the methods in NewClass
  • The idea is that the methods in NewClass override the methods in RequiredClass, providing the needed functionality by means of calls on ExistingClass objects

Note that the class adapter and object adapter UML diagrams are different

  • That is to say, the structure of these two different kinds of adapters is not the same
  • However, they are both classified as the adapter pattern because their intent is exactly the same
  • They differ structurally because in the adapter case the client provides an interface and in the object case the client provides a class
  • It will also become evident later that there are other reasons or cases whether the object adapter is desirable

In the previous example, EventSim was the client, and it made use of the predefined RocketSim interface

  • This made it possible for the OozinozRocket class to be written to adapt to the existing PhysicalRocket class

Now suppose that the EvenSim client is coded to work directly with objects of the class Skyrocket

  • The following UML diagram illustrates this basic idea
  • Not surprisingly, the Skyrocket class has methods getMass(), getThrust(), and setSimTime()

The foregoing diagram didn’t show the server side, but the idea is similar to what it was before

  • There are two ways of stating what you want to do
  • 1. You want to use the methods of the existing PhysicalRocket class to support the functionality of the methods of the Skyrocket class
  • 2. You want, in one way or another, to be able to run the client code simulation on an object of the PhysicalRocket class

Under this scenario, presumably the methods have been implemented for the Skyrocket class

  • But we don’t care—we’re going to override them and call methods on a PhysicalRocket object in the overridden versions
  • The next UML diagram shows the outline of an object adapter solution to this problem

Before going any further, note the following

  • If Java supported multiple inheritance, in theory the OozinozSkyrocket class could be a subclass of both SkyRocket and PhysicalRocket
  • In that case, the Class Adapter could more or less be duplicated in solving this problem
  • However, multiple inheritance is a mess and Java eschews it
  • Therefore, it is necessary to seek an alternative solution

Before trying to complete the diagram it is possible to make this observation

  • The Class Adapter pattern relied on typing a parameter, for example, to an interface
  • The Object Adapter pattern relies on simple polymorphism
  • In the client code, a parameter would be typed to the superclass, Skyrocket, and a reference to the subclass, OozinozSkyrocket, could be passed to the client code

Note also that the simulation time variable, as in the previous example, has to be dealt with

  • Observe that in this most recent diagram, the authors have indicated something which wasn’t shown in the original generic diagram
  • Namely, on the client side there is a double instance variable simTime
  • It is marked with a # sign, meaning that it’s declared protected
  • That means that the new subclass under development will have access to its own simTime instance variable without resorting to a call to a getSimTime() method

Challenge 3.3

  • Complete the class diagram in Figure 3.6 to show a design that allows OozinozRocket objects to serve as Skyrocket objects.

The critical things to notice in this diagram are the following

  • As in the generic picture earlier, there is a navigability arrow from the subclass, the OozinozSkyrocket class, to the object class, the PhysicalRocket class
  • In the box representing the OozinozSkyrocket class an instance variable is shown—namely, a reference to an object of the PhysicalRocket class
  • It is this object in the subclass that gives the object adapter pattern its name

You should also notice that the setSimTime() method doesn’t have to be overridden

  • Its implementation in the Skyrocket class is suitable for the subclass and is simply inherited

Rather than doing the code of the OozinozSkyrocket class as a challenge, the book simply gives the code

  • This shows how an instance of the PhysicalRocket class is created and used to support the needed functionality
  • The code follows
the outset of the oozinozskyrocket class code
The outset of the OozinozSkyrocket class code.
  • package com.oozinoz.firework;
  • import com.oozinoz.simulation.*;
  • public class OozinozSkyrocket
  • extends Skyrocket
  • {
  • private PhysicalRocket rocket;
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;
  • }

Notice that you are calling methods from the PhysicalRocket class

  • Those versions of getMass() and getThrust() take a time parameter
  • Not surprisingly, at construction time, the parameter value is time = 0

Also notice that in theory you could write the constructor for the subclass to take in the construction parameters for a PhysicalRocket object

  • Then instead of passing in an instance of PhysicalRocket, it could be constructed inside the code for the OozinozSkyrocket constructor
  • This is not better, just an alternative
  • One way or the other, the OozinozSkyrocket class has to end up with a live PhysicalRocket reference inside
the method implementations in the oozinozskyrocket class code
The method implementations in the OozinozSkyrocket class code
  • public double getMass()
  • {
  • return rocket.getMass(simTime);
  • }
  • public double getThrust()
  • {
  • return rocket.getThrust(simTime);
  • }
compare the foregoing with the solution in the class adapter case
Compare the foregoing with the solution in the Class Adapter case:
  • public double getMass()
  • {
  • return getMass(time);
  • }
  • public double getThrust()
  • {
  • return getThrust(time);
  • }

In the Class Adapter case you make use of methods inherited from the PhysicalRocket class in order to implement the adapter methods

  • In the Object Adapter case, you receive a reference to or create an instance of the PhysicalRocket class and then call methods in the PhysicalRocket class on that object in order to implement the adapter methods

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.

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.
    • 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.

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.)


The book closes this section by stating that the object adapter approach is riskier than the class adapter approach

  • This was suggested by the answers to challenge 3.4
  • However, you do what you have to do
  • If no client interface is given, the object adapter works
  • The book additionally notes that if one of the methods in the client superclass had been declared final, meaning that it couldn’t be overridden, then we would have been screwed…
the end
The End?
  • The rest of the chapter is on the topic of adapting data for a JTable
  • This is an interesting, practical example that arises out of the Java API
  • If there is time, it will be covered in class
  • Otherwise, it will be up to students to read the sections in the book and the remainder of these overheads on their own
adapting data for a jtable
Adapting Data for a JTable
  • There is a class in the Java API, JTable, which is designed to display tables
  • The JTable class was written generally, so that it could accept data of various types as table entries
  • This was accomplished by providing an interface, TableModel
  • In theory, it would be possible to write a class adapter using the TableModel and some application domain class
  • The interface is shown on the next overhead

There are several reasons that typically for table data a form of object adapter is preferable

  • The first is that the contents of a table likely stem from a collection of domain objects, not from a single class
  • Also, it turns out that for many of the methods in the TableModel interface it is possible to provide default implementations

The Java API provides an abstract class, AbstractTableModel which includes default implementations of most of the methods in the interface

  • This is sort of like an incomplete Java adapter class
  • The Java API points out the following:
  • To create a concrete TableModel as a subclass of AbstractTableModel you need only provide implementations for the following three methods:
    • public intgetRowCount();
    • public intgetColumnCount();
    • public Object getValueAt(int row, int column);

A UML diagram for the AbstractTableModel class is shown on the next overhead

  • It indicates the three methods, getColumnCount(), getRowCount(), and getValueAt()
  • Presumably these methods are declared abstract in the class
  • That’s how come you need to write a concrete subclass that implements them

Now it’s possible to use the Object Adapter design pattern with this class

  • In the book’s example, the RocketTableModel class extends the AbstractTableModel class
  • The RocketTableModel class implements, among other things, the three needed methods
  • It also has an array of instances of the Rocket class which are the source of information for rows in the table
  • This is shown in the next diagram

Notice that the UML diagram for the RocketTableModel shows two instance variables, one an array of rockets, another an array of column names

  • A constructor is shown for the class which takes an array of rockets as an input parameter
  • Also, in addition to the 3 expected methods, an additional method, getColumnName() is shown

AbstractTableModel implements the TableModel interface

  • By having RocketTableModel extend AbstractTableModel, you are creating an object adapter
  • This approach is handy because the RocketTableModel can have a handle on multiple instances of the Rocket class
  • Witness the array of rockets instance variable and parameter in the constructor

It is also conceptually necessary to have an object adapter rather than a class adapter

  • Under the Class Adapter design pattern you would write an adapter which implemented the interface directly and extended the Rocket class
  • But this wouldn’t make sense, because the purpose of the adapter in this example is to extract information about more than one rocket
  • Such a Class Adapter class would not be a subclass of the Rocket class, as needed in order for that design pattern to be applied

The book restates the characteristics of the two kinds of adapters in this way:

  • A class adapter subclasses an existing class and implements a target interface
  • An object adapter subclasses a target class and delegates to an existing class
  • The use of the word delegates is worth remembering
  • The composition/navigability arrow in the diagram indicates that the RocketTableModel makes use of multiple instances of the Rocket class
  • This is succinctly summarized in the term “delegates”

The book finally illustrates the purpose of all of this with a screenshot

  • It follows on the next overhead

Next the book gives partial code for an implementation of the RocketTableModel class

  • Since the missing pieces are marked “Challenge!” you can predict what comes after the partial code
  • The code follows

import javax.swing.table.*;

  • import com.oozinoz.firework.Rocket;
  • public class RocketTableModel extends AbstractTableModel
  • {
  • protected Rocket[] rockets;
  • protected String[] columnNames = new String[] { "Name", "Price", "Apogee" };
  • public RocketTableModel(Rocket[] rockets)
  • {
  • this.rockets = rockets;
  • }

public intgetColumnCount()

  • {
  • // Challenge!
  • }
  • public String getColumnName(inti)
  • {
  • // Challenge!
  • }
  • public intgetRowCount()
  • {
  • // Challenge!
  • }
  • public Object getValueAt(int row, intcol)
  • {
  • // Challenge!
  • }

Challenge 3.5

  • Fill in the code for the RocketTableModel methods that adapt an array of Rocket objects to serve as a TableModel

import javax.swing.table.*;

  • import com.oozinoz.firework.Rocket;
  • public class RocketTableModel extends AbstractTableModel {
  • protected Rocket[] rockets;
  • protected String[] columnNames = new String[] { "Name", "Price", "Apogee" };
  • public RocketTableModel(Rocket[] rockets)
  • {
  • this.rockets = rockets;
  • }

public intgetColumnCount()

  • {
  • return columnNames.length;
  • }
  • public String getColumnName(inti)
  • {
  • return columnNames[i];
  • }
  • public intgetRowCount()
  • {
  • return rockets.length;
  • }

public Object getValueAt(int row, intcol)

  • {
  • switch (col)
  • {
  • case 0:
  • return rockets[row].getName();
  • case 1:
  • return rockets[row].getPrice();
  • case 2:
  • return new Double(rockets[row].getApogee());
  • default:
  • return null;
  • }
  • }

The book provides example application code which uses the RocketTableModel adapter

  • In this code, instances of Rocket are created and placed in an array
  • An instance of RocketTableModel is constructed with the rocket array passed in as a parameter
  • Swing classes are used to display the table
  • Code for this example application follows

import java.awt.Component;

  • import java.awt.Font;
  • import javax.swing.*;
  • import com.oozinoz.firework.Rocket;
  • import com.oozinoz.utility.Dollars;
  • public class ShowRocketTable
  • {
  • public static void main(String[] args)
  • {
  • setFonts();
  • JTable table = new JTable(getRocketTable());
  • table.setRowHeight(36);
  • JScrollPane pane = new JScrollPane(table);
  • pane.setPreferredSize(new java.awt.Dimension(300, 100));
  • display(pane, " Rockets");
  • }

public static void display(Component c, String title)

  • {
  • JFrame frame = new JFrame(title);
  • frame.getContentPane().add(c);
  • frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  • frame.pack();
  • frame.setVisible(true);
  • }
  • private static RocketTableModelgetRocketTable()
  • {
  • Rocket r1 = new Rocket("Shooter", 1.0, new Dollars(3.95), 50.0, 4.5);
  • Rocket r2 = new Rocket("Orbit", 2.0, new Dollars(29.03), 5000, 3.2);
  • return new RocketTableModel(new Rocket[] { r1, r2 });
  • }
  • private static void setFonts()
  • {
  • Font font = new Font("Dialog", Font.PLAIN, 18);
  • UIManager.put("Table.font", font);
  • UIManager.put("TableHeader.font", font);
  • }

The book sums up this example in this way

  • The ShowRocketTable class is a short application that can show rocket information in an instance of JTable
  • It can be short and sweet because of the existence of the TableModel interface, the AbstractTableModel class, and the RocketTableModel class which extends the abstract class

The RocketTableModel implements the object adapter design pattern

  • It has instances of the Rocket class in it
  • It is information about these instances of the Rocket class that is used to fill the rows of the JTable generated by the ShowRocketTable application
  • In other words, the JTable class can’t know in advance which of the many types of data an application may wish to display in its cells
  • The adapter design adapts rocket data for display in a JTable
identifying adapters
Identifying Adapters
  • Consider the following UML diagram for the Java MouseAdapter class, and the challenge that follows it

Challenge 3.6

  • Are you applying the Adapter pattern when you use the MouseAdapter class? Explain how (or why not).

Solution 3.6

  • One argument: When the user clicks the mouse, I need to translate, or adapt, the resulting Swing call into an appropriate action. In other words, when I need to adapt GUI events to my application’s interface, I use Swing adapter classes. I am translating from one interface to another, fulfilling the intent of the Adapter pattern.

A counterargument: The “adapter” classes in Swing are stubs: They don’t translate or adapt anything. You subclass these classes, overriding the methods you need to do something. If anything, it is your methods and your class that form an example of Adapter. Had the Swing “adapter” been named something like DefaultMouseListener, this argument never would have arisen.

  • A class adapter implements an interface and extends a class in order to adapt the class to the interface
  • An object adapter extends a class and makes use of objects in order to adapt the objects to the class
  • JTable, TableModel, and AbstractTableModel provide examples of an adapter pattern in the Java API
  • For practical and conceptual reasons, the table example is an example of an object adapter
  • If you have a grip on the basic idea underlying adapters, you may be able to use them in your own code