Computer Science Design Patterns/Adapter

From Wikibooks, open books for an open world
Jump to: navigation, search

Contents

Example - Object Adapter [edit]

Ruby [edit]

class Adaptee
  def specific_request
    # do something
  end
end
 
class Adapter
  def initialize(adaptee)
    @adaptee = adaptee
  end
 
  def request
    @adaptee.specific_request
  end
end
 
client = Adapter.new(Adaptee.new)
client.request

Python [edit]

class Adaptee:
    def specific_request(self):
        return 'Adaptee'
 
class Adapter:
    def __init__(self, adaptee):
        self.adaptee = adaptee
 
    def request(self):
        return self.adaptee.specific_request()
 
client = Adapter(Adaptee())
print client.request()

Java [edit]

Before [edit]

Because the interface between Line and Rectangle objects is incompatible, the user has to recover the type of each shape and manually supply the correct arguments.

class LegacyLine {
    public void draw(int x1, int y1, int x2, int y2) {
        System.out.println("line from (" + x1 + ',' + y1 + ") to (" + x2 + ','
          + y2 + ')');
    }
}
class LegacyRectangle {
    public void draw(int x, int y, int w, int h) {
        System.out.println("rectangle at (" + x + ',' + y + ") with width " + w
          + " and height " + h);
    }
}
public class AdapterDemo {
    public static void main(String[] args) {
        Object[] shapes = {
            new LegacyLine(), new LegacyRectangle()
        };
        // A begin and end point from a graphical editor
        int x1 = 10, y1 = 20;
        int x2 = 30, y2 = 60;
 
        for (Object obj : shapes) {
            if (obj instanceof LegacyLine) {
                ((LegacyLine)obj).draw(x1, y1, x2, y2);
            } else if (obj instanceof LegacyRectangle) {
                ((LegacyRectangle)obj).draw(Math.min(x1, x2), Math.min(y1, y2),
                  Math.abs(x2 - x1), Math.abs(y2 - y1));
            }
        }
    }
}
// Line from (10,20) to (30,60)
// Rectangle at (10,20) with width 20 and height 40

After [edit]

The Adapter’s “extra level of indirection” takes care of mapping a user-friendly common interface to legacy-specific peculiar interfaces.

class LegacyLine {
 
    public void draw(int x1, int y1, int x2, int y2) {
        System.out.println("line from (" + x1 + ',' + y1 + ") to (" + x2 + ',' + y2 + ')');
    }
 
}
class LegacyRectangle {
 
    public void draw(int x, int y, int w, int h) {
        System.out.println("rectangle at (" + x + ',' + y + ") with width " + w + " and height " + h);
    }
 
}
interface Shape {
 
    void draw(int x1, int y1, int x2, int y2);
 
}
class Line implements Shape {
 
    private LegacyLine adaptee = new LegacyLine();
 
    public void draw(int x1, int y1, int x2, int y2) {
        adaptee.draw(x1, y1, x2, y2);
    }
 
}
class Rectangle implements Shape {
 
    private LegacyRectangle adaptee = new LegacyRectangle();
 
    public void draw(int x1, int y1, int x2, int y2) {
        adaptee.draw( Math.min(x1, x2), Math.min(y1, y2),
                      Math.abs(x2 - x1),  Math.abs(y2 - y1) );
    }
 
}
public class AdapterDemo {
 
    public static void main(String[] args) {
        Shape[] shapes = {new Line(), new Rectangle()};
        // A begin and end point from a graphical editor
        int x1 = 10, y1 = 20;
        int x2 = 30, y2 = 60;
        for (Shape shape : shapes) {
          shape.draw(x1, y1, x2, y2);
        }
    }
 
}
// Line from (10, 20) to (30, 60)
// Rectangle at (10, 20) with width 20 and height 40

Example - Class Adapter [edit]

Python [edit]

class Adaptee1:
    def __init__(self, *args, **kw):
        pass
 
    def specific_request(self):
        return 'Adaptee1'
 
class Adaptee2:
    def __init__(self, *args, **kw):
        pass
 
    def specific_request(self):
        return 'Adaptee2'
 
class Adapter(Adaptee1, Adaptee2):
    def __init__(self, *args, **kw):
        Adaptee1.__init__(self, *args, **kw)
        Adaptee2.__init__(self, *args, **kw)
 
    def request(self):
        return Adaptee1.specific_request(self), Adaptee2.specific_request(self)
 
client = Adapter()
print client.request()