The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

17
The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1

Transcript of The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Page 1: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

The Adapter Pattern

SE-2811Dr. Mark L. Hornick

1

Page 2: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Scenario: An Existing System (your client code) interfaces to a Vendor Class library you purchased and incorporated into an application your company is currently selling

Existing System

Vendor1 Class

The Vendor goes out of business; what do you do???

Vendor1 interface

Page 3: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

The original configuration

SE-2811Dr. Mark L. Hornick

3

The ClientApp is writtensuch that it is heavily dependenton the functionality implementedin ServiceProvider, and is loadedwith calls to various ServiceProvidermethods.

ServiceProvider may implementnumerous methods in a real situation;not only the few methods shown here

Page 4: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Adapter (Wrapper) Pattern

Existing System

Vendor2 Class

Vendor2 Class

Existing System

Adapter

Adapter• Implements the

interface your classes expect

• And talks to the vendor interface to service your requests.

Page 5: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

The Adapter configuration

1. The original ServiceProvider class is obsolete and discarded

2. An interface declaring the same methodsas the original ServiceProvider is created

3. A replacement classfor the originalServiceProvider is found that providessimilar functionality,but with a differentset of methods: the adaptee

4. An adapter class is writtenwhich maps calls from the original methods to the new methods

Page 6: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

The Adapter Pattern features The client makes a request to the adapter by calling a

method on it by continuing to program to the interface that mimics the methods of the original class.

The adapter translates the request into one or more calls on the adaptee The amount of code is usually small, but may be complex due

to indirect mappings from the original methods to the new methods.

The adapter transforms data or results from the adaptee into the form expected by the client The client receives the results of the call and doesn’t care that

there is an adapter doing the translation. The only change to the client is that it must create an instance

of the adapter rather than the original vendor class.

Page 7: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Cases to use Adapter

Legacy code exists that interfaces to a class library that has changed Revision change Vendor change

New application is being developed that will have to interface to a class library that has yet to be defined Define an interface and write the adapter later

SE-2811Dr. Mark L. Hornick

7

Page 8: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

The Façade Pattern

SE-2811Dr. Mark L. Hornick

8

Page 9: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Watching a Movie...

Use multiple interfaces (remotes) to Turn on Receiver/amplifier Turn on TV/Monitor Turn on DVD player Set the Receiver input to DVD Put the Monitor in HDMI input mode Set the Receiver volume to medium Set Receiver to DTS Surround Start the DVD player.

Interacting with the following classes:• Receiver/Amplifier• TV/Monitor• DVD

Page 10: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

To decrease the complexity..

We can create a new class TheaterFacade (e.g. a universal remote) which exposes a few methods such as watchMovie().

The façade treats the various components as a sub system and calls on them to implement the watchMovie method.

So to watch a movie, we just call one method, watchMovie and it communicates with the Monitor, DVD, and Receiver for us.

The façade still leaves the subsystem accessible to be used directly. If you need the advanced functionality of the subsystem classes, they are available for use.

Page 11: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

The Problem

Complex system Consisting of multiple

subsystems Each with its own interface,

each with many methods

Difficult for clients (blue) to deal with

Page 12: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Facade Solution

Solution Centralize subsystem

interface Simplify/reduce number of

centralized methods Façade presents new

unified “face” to clients Facade

Page 13: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Removing the burden from beginning Java developers with a Façade (WinPlotter)

SE-2811Dr. Mark L. Hornick

13

class winPlotter

DrawingWindow

- currentPenColor: java.awt.Color- items: java.util.ArrayList- contentPane: java.awt.Container- showGrid: boolean- backgroundColor: java.awt.Color- xinc: int- yinc: int- gridColor: java.awt.Color- drawPanel: DrawPanel

+ DrawingWindow()+ setWindowSize(x :int, y :int) : void+ erase() : void+ setWindowTitle(title :String) : void+ setPenColor(c :Color) : void+ setBackgroundColor(backgroundColor :Color) : void+ drawLineTo(x :int, y :int) : void+ moveTo(x :int, y :int) : void+ drawPointAt(x :int, y :int) : void+ textAt(x :int, y :int, text :String) : void+ setGrid(showGrid :boolean, xinc :int, yinc :int, gridColor :Color) : void+ paint(gr :Graphics) : void

DrawPanel

# paintComponent(g :Graphics) : void+ doPaint(gr :Graphics) : void

DrawItem

+ MOVE: int = 0 {readOnly}+ DRAW: int = 1 {readOnly}+ POINT: int = 2 {readOnly}+ TEXT: int = 3 {readOnly}+ opCode: int+ x: int = 0+ y: int = 0+ text: String+ color: Color

+ DrawItem(x :int, y :int, opCode :int, color :Color)+ DrawItem(x :int, y :int, opCode :int, color :Color, text :String)

FrameWindowConstants

AccessibleRootPaneContainer

TransferHandler.HasGetTransferHandler

swing::JFrame

+ EXIT_ON_CLOSE: int = 3 {readOnly}- defaultLookAndFeelDecoratedKey: Object = new StringBuffe... {readOnly}- defaultCloseOperation: int = HIDE_ON_CLOSE- transferHandler: TransferHandler# rootPane: JRootPane# rootPaneCheckingEnabled: boolean = false# accessibleContext: AccessibleContext = null

+ JFrame()+ JFrame(gc :GraphicsConfiguration)+ JFrame(title :String)+ JFrame(title :String, gc :GraphicsConfiguration)# frameInit() : void# createRootPane() : JRootPane# processWindowEvent(e :WindowEvent) : void+ setDefaultCloseOperation(operation :int) : void+ getDefaultCloseOperation() : int+ setTransferHandler(newHandler :TransferHandler) : void+ getTransferHandler() : TransferHandler+ update(g :Graphics) : void+ setJMenuBar(menubar :JMenuBar) : void+ getJMenuBar() : JMenuBar# isRootPaneCheckingEnabled() : boolean# setRootPaneCheckingEnabled(enabled :boolean) : void# addImpl(comp :Component, constraints :Object, index :int) : void+ remove(comp :Component) : void+ setLayout(manager :LayoutManager) : void+ getRootPane() : JRootPane# setRootPane(root :JRootPane) : void+ setIconImage(image :Image) : void+ getContentPane() : Container+ setContentPane(contentPane :Container) : void+ getLayeredPane() : JLayeredPane+ setLayeredPane(layeredPane :JLayeredPane) : void+ getGlassPane() : Component+ setGlassPane(glassPane :Component) : void+ getGraphics() : Graphics+ repaint(time :long, x :int, y :int, width :int, height :int) : void+ setDefaultLookAndFeelDecorated(defaultLookAndFeelDecorated :boolean) : void+ isDefaultLookAndFeelDecorated() : boolean# paramString() : String+ getAccessibleContext() : AccessibleContext

JComponentAccessible

swing::JPanel

- uiClassID: String = "PanelUI" {readOnly}

+ JPanel(layout :LayoutManager, isDoubleBuffered :boolean)+ JPanel(layout :LayoutManager)+ JPanel(isDoubleBuffered :boolean)+ JPanel()+ updateUI() : void+ getUI() : PanelUI+ setUI(ui :PanelUI) : void+ getUIClassID() : String- writeObject(s :ObjectOutputStream) : void# paramString() : String+ getAccessibleContext() : AccessibleContext

::Lab1App

«facade»WinPlotter

- window: DrawingWindow- width: int- height: int- xmin: int- ymin: int- xmax: int- ymax: int- xscale: float- yscale: float- showGrid: boolean

+ WinPlotter()- logicalToPixel(xlog :int, ylog :int) : Point+ drawTo(x :int, y :int) : void+ erase() : void+ moveTo(x :int, y :int) : void+ drawPoint(x :int, y :int) : void+ printAt(x :int, y :int, text :String) : void+ setBackgroundColor(red :int, green :int, blue :int) : void+ setPenColor(red :int, green :int, blue :int) : void+ setWindowSize(width :int, height :int) : boolean+ setPlotBoundaries(xmin :int, ymin :int, xmax :int, ymax :int) : boolean+ setGrid(showGrid :boolean, xinc :int, yinc :int, gridColor :Color) : boolean+ setWindowTitle(title :String) : void

+items

*

-drawPanel

-window

Page 14: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Generic Pattern

SE-2811Dr. Mark L. Hornick

14

Page 15: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Facade Consequences

Shields clients from subsystem components Make subsystem easier to use

Reduces coupling from client to subsystem classes Allow internal classes to change freely Permit “layering” of system function Level of client-subsystem coupling

Make Facade an abstract class Different concrete subclasses for different implementations of

the subsystem. Configure the façade object with different subsystem

objects.

Page 16: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

SE-2811Dr. Mark L. Hornick

16

Page 17: The Adapter Pattern SE-2811 Dr. Mark L. Hornick 1.

Facade Applications

Interface to existing library Unify or “clean up” complex interface

Design layered system Various service levels Façade abstracts interface of each level

Provide abstract interfaces To alternative implementations