适配器模式

1. Adapters in the Real World

先想想我们生活中常见的适配器。

今天买了一个iPhone7,港版的。港版跟国行有个很大的区别是,电源插头不同。国内的三线插头与香港的三线插头形状是不同的。结果就是港版的插头想插到国内的插座上,而国内的插座只支持国内的插头。 怎么办呢?代购一般都很贴心,会赠送一个插头适配器

于是港版的插头先查到适配器上,然后适配器再查到国内的插座上。 本来国内只支持国内的插头,现在间接支持的香港的插头,功劳就在适配器。

再举一个例子: 棘齿螺丝刀(Ratchet)是两开口的,而插孔(Socket)是四开口的,两开口的不能直接拧四开口的。怎么办呢?中间加一层适配器,适配器有两面,上面是两开口,下面是四开口~

2. Adapters in GoF

The Adapter is known as a structural pattern,as it's used to identifying a simple way to realize relationships between entities. Thedefinition of Adapter provided in the original Gang of Four book on DesignPatterns states:

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

3. 什么时候用

  • A class to be used doesn't meet interface requirements.
  • Complex conditions tie object behavior to its state.
  • Transitions between states need to be explicit.

4. 要点

引用自:Adapter

  1. Identify the players: the component(s) that want to be accommodated (i.e. the client), and the component that needs to adapt (i.e. the adaptee).
  2. Identify the interface that the client requires.
  3. Design a "wrapper" class that can "impedance match" the adaptee to the client.
  4. The adapter/wrapper class "has a" instance of the adaptee class.
  5. The adapter/wrapper class "maps" the client interface to the adaptee interface.
  6. The client uses (is coupled to) the new interface.

5.经验法则

  • Adapter makes things work after they're designed; Bridge makes them work before they are.
  • Bridge is designed up-front to let the abstraction and the implementation vary independently. Adapter is retrofitted to make unrelated classes work together.
  • Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface.
  • Adapter is meant to change the interface of an existing object. Decorator enhances another object without changing its interface. Decorator is thus more transparent to the application than an adapter is. As a consequence, Decorator supports recursive composition, which isn't possible with pure Adapters.
  • Facade defines a new interface, whereas Adapter reuses an old interface. Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one.

6.代码示例

Adapter Design Pattern in Java: Before and after 先看一段没有适配器的场景。 假设之前有两种四边形的工具类,一种是画线Line,输入四个点的位置;另一种是画长方形Rectangle,输入左上角的坐标,还有长和宽。 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 (int i = 0; i < shapes.length; ++i)
          if (shapes[i].getClass().getName().equals("LegacyLine"))
            ((LegacyLine)shapes[i]).draw(x1, y1, x2, y2);
          else if (shapes[i].getClass().getName().equals("LegacyRectangle"))
            ((LegacyRectangle)shapes[i]).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

加入适配器角色: 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 (int i = 0; i < shapes.length; ++i)
          shapes[i].draw(x1, y1, x2, y2);
    }
}

输出:

line from (10,20) to (30,60)
rectangle at (10,20) with width 20 and height 40

转载于:https://my.oschina.net/damon4u/blog/750617

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值