再战设计模式(五)之适配器模式

什么是适配器模式?

  将一个类的接口转换成客户希望的另外一个接口,adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作.

模式中的角色

  1. 目标接口(target):客户期待的接口,目标可以是具体的或抽象 的类,也可以是接口。
  2. 需要适配的类(adaptee): 需要适配的类或者适配类
  3. 适配器(adapter): 通过包装一个需要适配的对象,把原接口转换成目标接口
/**
 * @Created by xiaodao
 * 鸭子的接口
 */
public interface Duck {

    void fly();
    //鸭叫声
    void quack();
}
/**
 * @Created by xiaodao
 * 野鸭子
 */
public class MallardDuck implements Duck {
    public void fly() {
        System.out.println("i'm flying");
    }

    /**
     * 鸭子叫
     */
    public void quack() {

        System.out.println("呱呱呱...");
    }
}
/**
 * @Created by xiaodao
 * 火鸡
 */
public interface Turkey {

    void fly();

    /**
     * 火鸡咯咯叫
     */
    void gobble();
}
/**
 * @Created by xiaodao
 */
public class WildTurkey implements Turkey {
    public void fly() {
        System.out.println("我飞的不高");

    }

    public void gobble() {

        System.out.println("咯咯叫");
    }
}

适配器:

/**
 * @Created by xiaodao
 * 火鸡适配器 要适配成鸭子
 */
public class TurkeyAdapter implements Duck{

    private  Turkey turkey;

    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }

    public void fly() {
        turkey.fly();

    }

    public void quack() {
        for (int i = 0; i <2 ; i++) {
            turkey.gobble();
        }

    }
}
/**
 * @Created by xiaodao
 */
public class Main {

    public static void main(String[] args) {
        Turkey turkey =new WildTurkey();
        //这里我只需要把火鸡丢到适配器里.他就可以变成鸭子.
        Duck duck = new TurkeyAdapter(turkey);
        duck.fly();
        duck.quack();

    }
}

类图:

再战设计模式(五)之适配器模式

类图也不是太复杂,调用者创建了俩个对象一个是适配器 一个是被适配的实例 目标是适配成鸭子 

在这里duck的角色就是目标对象(target) 我们缺少一直鸭子,需要来一个火鸡来冒充它

turkey充当被适配的对象(adaptee) 火鸡也会飞也会叫 

TurkeyAdapter 火鸡适配器 我们把火鸡适配成鸭子的具体实现就在这里.

适配器的分类

1.类适配器模式

主要是在adapter类extends 继承被适配者 (如果以上图为例的话,extends wildTurkey )

这样的话我个人认为是扩展没有对象适配器好,这个还是要看业务来使用

2.对象适配模式或者叫组合模式

主要是使用adapter类引用被适配的.组合起来 就是上图这样.

jdk中应用到的地方

再战设计模式(五)之适配器模式

inputStreamReader 就是扮演了adapter的角色

他有inputStream的引用 这里用StreamDecoder表示,因为从byte到char 需要解码操作inputStream 是adaptee角色

inputStreamReader 继承了 reader 抽象类  reader 就是target

总结:

adapter是现有的类,进行适配成为新的类. 当我们在项目中有新的改动,但是还需要兼容过去的东西的时候,可以尝试使用适配器模式,但是不要去改动旧的代码,不然还需要测试一遍旧的代码.

例子虽然很简单, 但是最重要的是思想,我也和大家一起在细细品味.争取融入到我们的代码中,变成代码功底