定义


适配器模式

适配器模式将一个类的接口转换成客户端所期待的另一种接口,使原本因接口不兼容而无法协同工作的类可以一起工作。

角色


  1. Target(目标接口):客户端期待的接口,客户端只面向该接口编程。
  2. Adaptee(被适配者):现存的、需要被适配的类或接口(通常是遗留代码、第三方 SDK 等)。
  3. Adapter(适配器):核心转换器,它实现了 Target 接口,并在内部调用 Adaptee 的功能,完成接口转换。
  4. Client(客户端):使用 Target 接口的调用方。

实现


对象适配器

适配器持有被适配者的引用实现。

// Target
public interface Logger {
    void info(String msg);
    void error(String msg);
}
 
// Adaptee
public class ThirdPartyLog {
    public void write(String level, String message) {
        System.out.println("[" + level + "] " + message);
    }
}
 
// Adapter:组合 Adaptee,实现Target
public class ThirdPartyLogAdapter implements Logger {
    private final ThirdPartyLog adaptee;
 
    public ThirdPartyLogAdapter(ThirdPartyLog adaptee) {
        this.adaptee = adaptee;
    }
 
    @Override
    public void info(String msg) {
        adaptee.write("INFO", msg);   
    }
 
    @Override
    public void error(String msg) {
        adaptee.write("ERROR", msg);
    }
}
 
// Client
public class Client {
    public static void main(String[] args) {
        Logger logger = new ThirdPartyLogAdapter(new ThirdPartyLog());
        logger.info("启动成功");
        logger.error("连接超时");
    }
}

类适配器

适配器同时继承被适配者并实现Target。

public class ThirdPartyLogClassAdapter extends ThirdPartyLog implements Logger {
    @Override
    public void info(String msg) {
        write("INFO", msg);   
    }
 
    @Override
    public void error(String msg) {
        write("ERROR", msg);
    }
}

接口适配器(缺省适配器)

当Target方法很多,而客户端只需要其中几个时,先用一个抽象类空实现,客户端只实现自己需要的部分。

public interface EventListener {
    void onStart(); void onPause(); void onResume();
    void onStop();  void onDestroy(); // ... 还有很多
}
 
// 缺省适配器:全部空实现
public abstract class EventListenerAdapter implements EventListener {
    public void onStart()   {}
    public void onPause()   {}
    public void onResume()  {}
    public void onStop()    {}
    public void onDestroy() {}
}
 
// 客户端只实现onStop
public class MyListener extends EventListenerAdapter {
    @Override
    public void onStop() {
        System.out.println("clean up");
    }
}