Difference between revisions of "Adapter"

From CDOT Wiki
Jump to: navigation, search
(Other)
(Object Adapter Pattern)
 
(59 intermediate revisions by the same user not shown)
Line 2: Line 2:
  
 
== Adapter Design Pattern ==
 
== Adapter Design Pattern ==
 +
Adapter, a Structural Pattern and also referred to as a '''wrapper''', is most commonly used when you want to reuse a class to work with a target class but are constrained by incompatible interfaces. The idea is to convert the interface of a reusable class into an interface that ''your'' classes expect.
  
 +
A good analogy for the Adapter pattern would be the adapters that are commonly used to convert the voltage of Canadian/U.S made appliances to be used in different countries. In this case, the appliance ('''Target''') is using the adapter ('''Adapter''') to reuse the socket ('''Adaptee''') already in place.
  
 +
There are two specific types of adapter patterns - ''object adapter pattern'' and ''class adapter pattern''. The latter uses multiple inheritance whereas the former uses an instance of the reuseable class it wants to adapt. Between the two, object adapter pattern is the favored one due to the fact that popular languages such as Java do not support multiple inheritance.
  
== Adapter UML Diagrams ==
+
== Object Adapter ==
 +
This adapter pattern uses an instance of the class it wraps. By using an instance, methods belonging to the wrapped object can be invoked.
  
 +
[[Image:objectadapter_diag_rueen2.GIF]]
 +
 +
== Class Adapter ==
 +
This adapter pattern uses multiple inheritance as a means to wrap the reusable class and use its functionality.
 +
 +
[[Image:classadapter_diag_rueen.GIF]]
 +
 +
== Adapter UML Diagram ==
 +
UML diagram example of the Adapter pattern. Specifically, the class adapter pattern
 +
 +
[[Image:Adapter_diag.gif]]
 +
 +
Image source: http://www.dofactory.com/Patterns/Diagrams/adapter.gif (''Copyright 2001 - 2007 Data & Object Factory.'')
  
 
== Code Examples ==
 
== Code Examples ==
 +
'''Java'''
 +
 +
FreeMind - GNU General Public License.
 +
 +
FreeMind's [http://www.google.com/codesearch?hl=en&q=show:SSjMlfyYK2U:RCv_23t_s7k:tpy_iiX4ncI&sa=N&ct=rd&cs_p=http://gentoo.osuosl.org/distfiles/freemind-src-0_7_1.tar.gz&cs_f=freemind/freemind/modes/ArrowLinkAdapter.java File Repository]
 +
 +
 +
Explanation:
 +
 +
In this example, an ArrowLinkAdapter is created to be used to adapt different arrow shaped links in FreeMind's MindMap area. ArrowLinkAdapter.java is the '''Adapter''' and LinkAdapter.java is the '''Adaptee'''. Even though LinkAdapter is an adapter itself, it is infact the adaptee in this case.
 +
 +
 +
 +
'''ArrowLinkAdapter.java'''
 +
 +
<pre>
 +
/*FreeMind - A Program for creating and viewing Mindmaps
 +
*Copyright (C) 2000-2001  Joerg Mueller <joergmueller@bigfoot.com>
 +
*See COPYING for Details
 +
*
 +
*This program is free software; you can redistribute it and/or
 +
*modify it under the terms of the GNU General Public License
 +
*as published by the Free Software Foundation; either version 2
 +
*of the License, or (at your option) any later version.
 +
*
 +
*This program is distributed in the hope that it will be useful,
 +
*but WITHOUT ANY WARRANTY; without even the implied warranty of
 +
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +
*GNU General Public License for more details.
 +
*
 +
*You should have received a copy of the GNU General Public License
 +
*along with this program; if not, write to the Free Software
 +
*Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 +
*/
 +
/*$Id: ArrowLinkAdapter.java,v 1.4 2003/12/07 21:00:19 christianfoltin Exp $*/
 +
 +
package freemind.modes;
 +
import freemind.modes.LinkAdapter;
 +
import freemind.main.FreeMindMain;
 +
 +
import java.awt.Point;
 +
 +
public abstract class ArrowLinkAdapter extends LinkAdapter implements MindMapArrowLink {
 +
 +
    /** the zero is the start point of the line;*/
 +
    protected Point startInclination;
 +
    /** the zero is the start point of the line;*/
 +
    protected Point endInclination;
 +
    protected String startArrow;
 +
    protected String endArrow;
 +
 +
 +
    public ArrowLinkAdapter(MindMapNode source,MindMapNode target,FreeMindMain frame)  {
 +
        super(source, target, frame, "standardlinkcolor", "standardlinkstyle");
 +
        startArrow = "None";
 +
        endArrow = "Default";
 +
    }
 +
 +
    public Point getStartInclination() { return startInclination; }
 +
    public Point getEndInclination() { return endInclination; }
 +
    public String getStartArrow() { return startArrow; }
 +
    public String getEndArrow() { return endArrow; }
 +
 +
    public void  setStartInclination(Point startInclination) {  this.startInclination=startInclination; }
 +
    public void  setEndInclination(Point endInclination) {  this.endInclination=endInclination; }
 +
    public void  setStartArrow(String startArrow) {
 +
        if(startArrow == null || startArrow.toUpperCase().equals("NONE")) {
 +
            this.startArrow = "None";
 +
            return;
 +
        } else if(startArrow.toUpperCase().equals("DEFAULT")) {
 +
            this.startArrow = "Default";
 +
            return;
 +
        }
 +
        // dont change:
 +
        System.err.println("Cannot set the start arrow type to " + startArrow);
 +
    }
 +
    public void  setEndArrow(String endArrow) {
 +
        if(endArrow == null || endArrow.toUpperCase().equals("NONE")) {
 +
            this.endArrow = "None";
 +
            return;
 +
        } else if(endArrow.toUpperCase().equals("DEFAULT")) {
 +
            this.endArrow = "Default";
 +
            return;
 +
        }
 +
        // dont change:
 +
        System.err.println("Cannot set the end arrow type to " + endArrow);
 +
    }
 +
 +
    public Object clone() {
 +
        ArrowLinkAdapter arrowLink = (ArrowLinkAdapter) super.clone();
 +
        // now replace the points:
 +
        arrowLink.startInclination = (startInclination==null)?null:new Point(startInclination.x, startInclination.y);
 +
        arrowLink.endInclination = (endInclination==null)?null:new Point(endInclination.x, endInclination.y);
 +
        arrowLink.startArrow = (startArrow==null)?null:new String(startArrow);
 +
        arrowLink.endArrow = (endArrow==null)?null:new String(endArrow);
 +
        return arrowLink;
 +
    }
 +
 +
}
 +
 +
</pre>
 +
 +
'''LinkAdapter'''
 +
 +
<pre>
 +
/*FreeMind - A Program for creating and viewing Mindmaps
 +
*Copyright (C) 2000-2001  Joerg Mueller <joergmueller@bigfoot.com>
 +
*See COPYING for Details
 +
*
 +
*This program is free software; you can redistribute it and/or
 +
*modify it under the terms of the GNU General Public License
 +
*as published by the Free Software Foundation; either version 2
 +
*of the License, or (at your option) any later version.
 +
*
 +
*This program is distributed in the hope that it will be useful,
 +
*but WITHOUT ANY WARRANTY; without even the implied warranty of
 +
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +
*GNU General Public License for more details.
 +
*
 +
*You should have received a copy of the GNU General Public License
 +
*along with this program; if not, write to the Free Software
 +
*Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 +
*/
 +
/*$Id: LinkAdapter.java,v 1.3 2003/11/29 17:12:33 christianfoltin Exp $*/
 +
 +
package freemind.modes;
 +
import freemind.modes.LineAdapter;
 +
import freemind.main.FreeMindMain;
 +
 +
public abstract class LinkAdapter extends LineAdapter implements MindMapLink {
 +
 +
    String destinationLabel;
 +
    String referenceText;
 +
    MindMapNode source;
 +
 +
    public LinkAdapter(MindMapNode source,MindMapNode target,FreeMindMain frame)  {
 +
        this(source,target, frame, "standardlinkcolor", "standardlinkstyle");
 +
    }
 +
 +
    /** For derived classes.*/
 +
    protected  LinkAdapter(MindMapNode source,MindMapNode target,FreeMindMain frame, String standardColorPropertyString, String standardStylePropertyString)  {
 +
        super(target, frame, standardColorPropertyString, standardStylePropertyString);
 +
        this.source=source;
 +
        destinationLabel = null;
 +
        referenceText = null;
 +
    }
 +
 +
    public String getDestinationLabel() { return destinationLabel; }
 +
    public String getReferenceText(){ return referenceText; }
 +
    public MindMapNode getSource() { return source;}
 +
 +
    public void setSource(MindMapNode source) {this.source=source;}
 +
    public void setDestinationLabel(String destinationLabel) { this.destinationLabel = destinationLabel; }
 +
    public void setReferenceText(String referenceText) { this.referenceText = referenceText; }
 +
 +
//    public Object clone() {
 +
//        try {
 +
//            return super.clone();
 +
//        } catch(java.lang.CloneNotSupportedException e) {
 +
//            return null;
 +
//        }
 +
//    }
 +
  
 +
}
  
 +
</pre>
  
== Relevant Links ==
+
----
 +
'''C++'''
  
 +
KDEBluetooth - GNU General Public License
  
 +
KDEBluetooth [http://www.google.com/codesearch?hl=en&q=show:SWkEw1PFvDM:seiYnh_fPLA:RjuqBeXZiEM&sa=N&ct=rd&cs_p=http://members.xoom.alice.it/motaboy/kdebluetooth-20040128.tar.bz2&cs_f=kdebluetooth-20040128/libkbluetooth/adapter.h File Repository]
 +
 +
'''adapter.h'''
 +
 +
<pre>
 +
//-*-c++-*-
 +
/***************************************************************************
 +
*  Copyright (C) 2003 by Fred Schaettgen                                *
 +
*  kdebluetooth@0xF.de                                                  *
 +
*                                                                        *
 +
*  This program is free software; you can redistribute it and/or modify  *
 +
*  it under the terms of the GNU General Public License as published by  *
 +
*  the Free Software Foundation; either version 2 of the License, or    *
 +
*  (at your option) any later version.                                  *
 +
***************************************************************************/
 +
 +
#ifndef BTADAPTER_H
 +
#define BTADAPTER_H
 +
 +
#include <vector>
 +
#include <qstring.h>
 +
#include <qvaluevector.h>
 +
#include "deviceaddress.h"
 +
 +
namespace KBluetooth
 +
{
 +
 +
/** Class representing a local bluetooth adapter.
 +
* This class provides access to the properties of a local bluetooth
 +
* adapter. This class has no public constructors. You can get the
 +
* list of available adapters using KBluetooth::Adapters.
 +
*/
 +
class Adapter
 +
{
 +
    friend class Adapters;
 +
public:
 +
    enum ConnectionType { SCO = 0, ACL = 1 };
 +
    enum ConnectionState { NOT_CONNECTED, CONNECTED, CONNECTING, UNKNOWN_STATE };
 +
    struct ConnectionInfo {
 +
        DeviceAddress address;
 +
        int handle;
 +
        ConnectionType type;
 +
        ConnectionState state;
 +
        bool out;
 +
        uint link_mode;
 +
    };
 +
    typedef QValueVector<ConnectionInfo> ConnectionInfoVector;
 +
 +
    /** Returns the device address of the given adapter.
 +
    @return The device address
 +
    */
 +
    DeviceAddress getAddress() const;
 +
 +
    /** Returns the name of the adapter.
 +
    @return The device name
 +
    */
 +
    QString getName() const;
 +
 +
    /** Returns the index of the device.
 +
    @return device index
 +
    */
 +
    int getIndex() const;
 +
 +
    /** Return a deviceaddress for each ACL-Connection */
 +
    ConnectionInfoVector getAclConnections() const;
 +
 +
    ConnectionState getAclConnectionState(const DeviceAddress& addr) const;
 +
 +
protected:
 +
    /** Constructor used internally by KBluetooth::Adapters. */
 +
    Adapter(int index, const DeviceAddress& address, QString nameStr);
 +
private:
 +
    int index;
 +
    QString nameStr;
 +
    DeviceAddress address;
 +
};
 +
 +
 +
/** Enumerates the locally attached bluetooth devices.
 +
* The information in this class stays static until update()
 +
* is called.
 +
*/
 +
class Adapters
 +
{
 +
public:
 +
    /** Default constructor.
 +
    Calls update().
 +
    */
 +
    Adapters();
 +
 +
    /** Gets the number of adapters.
 +
    @return number of adapters
 +
    */
 +
    int count();
 +
 +
    /** Returns a single adapter
 +
    @param n index of the adapter (0 <= n < count())
 +
    @return adapter info
 +
    */
 +
    const Adapter& operator[](int n) const;
 +
 +
    /** Refreshes the list of adapters. */
 +
    void update();
 +
private:
 +
    std::vector<Adapter> adapters;
 +
    static int dev_info(int s, int dev_id, long arg);
 +
    void dev_info(int s, int dev_id);
 +
};
 +
 +
}
 +
 +
#endif
 +
 +
 +
</pre>
  
 
== Other ==
 
== Other ==
[http://zenit.senecac.on.ca/wiki/index.php/User:Rfiez-mo Rueen Fiez Wiki]
+
[http://zenit.senecac.on.ca/wiki/index.php/User:Rfiez-mo Rueen Fiez]<br />
 
+
[http://zenit.senecac.on.ca/wiki/index.php/BTP600 BTP600]<br />
 
<br />
 
<br />
 
<br />
 
<br />

Latest revision as of 15:11, 27 March 2007

Adapter Design Pattern

Adapter, a Structural Pattern and also referred to as a wrapper, is most commonly used when you want to reuse a class to work with a target class but are constrained by incompatible interfaces. The idea is to convert the interface of a reusable class into an interface that your classes expect.

A good analogy for the Adapter pattern would be the adapters that are commonly used to convert the voltage of Canadian/U.S made appliances to be used in different countries. In this case, the appliance (Target) is using the adapter (Adapter) to reuse the socket (Adaptee) already in place.

There are two specific types of adapter patterns - object adapter pattern and class adapter pattern. The latter uses multiple inheritance whereas the former uses an instance of the reuseable class it wants to adapt. Between the two, object adapter pattern is the favored one due to the fact that popular languages such as Java do not support multiple inheritance.

Object Adapter

This adapter pattern uses an instance of the class it wraps. By using an instance, methods belonging to the wrapped object can be invoked.

Objectadapter diag rueen2.GIF

Class Adapter

This adapter pattern uses multiple inheritance as a means to wrap the reusable class and use its functionality.

Classadapter diag rueen.GIF

Adapter UML Diagram

UML diagram example of the Adapter pattern. Specifically, the class adapter pattern

Adapter diag.gif

Image source: http://www.dofactory.com/Patterns/Diagrams/adapter.gif (Copyright 2001 - 2007 Data & Object Factory.)

Code Examples

Java

FreeMind - GNU General Public License.

FreeMind's File Repository


Explanation:

In this example, an ArrowLinkAdapter is created to be used to adapt different arrow shaped links in FreeMind's MindMap area. ArrowLinkAdapter.java is the Adapter and LinkAdapter.java is the Adaptee. Even though LinkAdapter is an adapter itself, it is infact the adaptee in this case.


ArrowLinkAdapter.java

/*FreeMind - A Program for creating and viewing Mindmaps
 *Copyright (C) 2000-2001  Joerg Mueller <joergmueller@bigfoot.com>
 *See COPYING for Details
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; if not, write to the Free Software
 *Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
/*$Id: ArrowLinkAdapter.java,v 1.4 2003/12/07 21:00:19 christianfoltin Exp $*/

package freemind.modes;
import freemind.modes.LinkAdapter;
import freemind.main.FreeMindMain;

import java.awt.Point;

public abstract class ArrowLinkAdapter extends LinkAdapter implements MindMapArrowLink {

    /** the zero is the start point of the line;*/
    protected Point startInclination;
    /** the zero is the start point of the line;*/
    protected Point endInclination;
    protected String startArrow;
    protected String endArrow;


    public ArrowLinkAdapter(MindMapNode source,MindMapNode target,FreeMindMain frame)  {
        super(source, target, frame, "standardlinkcolor", "standardlinkstyle");
        startArrow = "None";
        endArrow = "Default";
    }

    public Point getStartInclination() { return startInclination; }
    public Point getEndInclination() { return endInclination; }
    public String getStartArrow() { return startArrow; }
    public String getEndArrow() { return endArrow; }

    public void  setStartInclination(Point startInclination) {  this.startInclination=startInclination; }
    public void  setEndInclination(Point endInclination) {  this.endInclination=endInclination; }
    public void  setStartArrow(String startArrow) {
        if(startArrow == null || startArrow.toUpperCase().equals("NONE")) {
            this.startArrow = "None";
            return;
        } else if(startArrow.toUpperCase().equals("DEFAULT")) {
            this.startArrow = "Default";
            return;
        }
        // dont change:
        System.err.println("Cannot set the start arrow type to " + startArrow);
    }
    public void  setEndArrow(String endArrow) {
        if(endArrow == null || endArrow.toUpperCase().equals("NONE")) {
            this.endArrow = "None";
            return;
        } else if(endArrow.toUpperCase().equals("DEFAULT")) {
            this.endArrow = "Default";
            return;
        }
        // dont change:
        System.err.println("Cannot set the end arrow type to " + endArrow);
    }

    public Object clone() {
        ArrowLinkAdapter arrowLink = (ArrowLinkAdapter) super.clone();
        // now replace the points:
        arrowLink.startInclination = (startInclination==null)?null:new Point(startInclination.x, startInclination.y);
        arrowLink.endInclination = (endInclination==null)?null:new Point(endInclination.x, endInclination.y);
        arrowLink.startArrow = (startArrow==null)?null:new String(startArrow);
        arrowLink.endArrow = (endArrow==null)?null:new String(endArrow);
        return arrowLink;
    }

}

LinkAdapter

/*FreeMind - A Program for creating and viewing Mindmaps
 *Copyright (C) 2000-2001  Joerg Mueller <joergmueller@bigfoot.com>
 *See COPYING for Details
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; if not, write to the Free Software
 *Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
/*$Id: LinkAdapter.java,v 1.3 2003/11/29 17:12:33 christianfoltin Exp $*/

package freemind.modes;
import freemind.modes.LineAdapter;
import freemind.main.FreeMindMain;

public abstract class LinkAdapter extends LineAdapter implements MindMapLink {

    String destinationLabel;
    String referenceText;
    MindMapNode source;

    public LinkAdapter(MindMapNode source,MindMapNode target,FreeMindMain frame)  {
        this(source,target, frame, "standardlinkcolor", "standardlinkstyle");
    }

    /** For derived classes.*/
    protected  LinkAdapter(MindMapNode source,MindMapNode target,FreeMindMain frame, String standardColorPropertyString, String standardStylePropertyString)  {
        super(target, frame, standardColorPropertyString, standardStylePropertyString);
        this.source=source;
        destinationLabel = null;
        referenceText = null;
    }

    public String getDestinationLabel() { return destinationLabel; }
    public String getReferenceText(){ return referenceText; }
    public MindMapNode getSource() { return source;}

    public void setSource(MindMapNode source) {this.source=source;}
    public void setDestinationLabel(String destinationLabel) { this.destinationLabel = destinationLabel; }
    public void setReferenceText(String referenceText) { this.referenceText = referenceText; }

//     public Object clone() {
//         try {
//             return super.clone();
//         } catch(java.lang.CloneNotSupportedException e) {
//             return null;
//         }
//     }


}


C++

KDEBluetooth - GNU General Public License

KDEBluetooth File Repository

adapter.h

//-*-c++-*-
/***************************************************************************
 *   Copyright (C) 2003 by Fred Schaettgen                                 *
 *   kdebluetooth@0xF.de                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#ifndef BTADAPTER_H
#define BTADAPTER_H

#include <vector>
#include <qstring.h>
#include <qvaluevector.h>
#include "deviceaddress.h"

namespace KBluetooth
{

/** Class representing a local bluetooth adapter.
 * This class provides access to the properties of a local bluetooth
 * adapter. This class has no public constructors. You can get the
 * list of available adapters using KBluetooth::Adapters.
 */
class Adapter
{
    friend class Adapters;
public:
    enum ConnectionType { SCO = 0, ACL = 1 };
    enum ConnectionState { NOT_CONNECTED, CONNECTED, CONNECTING, UNKNOWN_STATE };
    struct ConnectionInfo {
        DeviceAddress address;
        int handle;
        ConnectionType type;
        ConnectionState state;
        bool out;
        uint link_mode;
    };
    typedef QValueVector<ConnectionInfo> ConnectionInfoVector;

    /** Returns the device address of the given adapter.
    @return The device address
    */
    DeviceAddress getAddress() const;

    /** Returns the name of the adapter.
    @return The device name
    */
    QString getName() const;

    /** Returns the index of the device.
    @return device index
    */
    int getIndex() const;

    /** Return a deviceaddress for each ACL-Connection */
    ConnectionInfoVector getAclConnections() const;

    ConnectionState getAclConnectionState(const DeviceAddress& addr) const;

protected:
    /** Constructor used internally by KBluetooth::Adapters. */
    Adapter(int index, const DeviceAddress& address, QString nameStr);
private:
    int index;
    QString nameStr;
    DeviceAddress address;
};


/** Enumerates the locally attached bluetooth devices.
 * The information in this class stays static until update()
 * is called.
 */
class Adapters
{
public:
    /** Default constructor.
    Calls update().
    */
    Adapters();

    /** Gets the number of adapters.
    @return number of adapters
    */
    int count();

    /** Returns a single adapter
    @param n index of the adapter (0 <= n < count())
    @return adapter info
    */
    const Adapter& operator[](int n) const;

    /** Refreshes the list of adapters. */
    void update();
private:
    std::vector<Adapter> adapters;
    static int dev_info(int s, int dev_id, long arg);
    void dev_info(int s, int dev_id);
};

}

#endif


Other

Rueen Fiez
BTP600




--Rueen 19:41, 17 January 2007 (EST)