23种常用设计模式之适配器模式

说明

适配器模式(Adapter)是一种结构型设计模式。顾名思义,主要作用就是用来做适配用的。之所以需要适配,是因为已有的代码不能很好的完成我们的业务逻辑,但是通过简单的适配,就可以满足我们的需求,避免重复编写很多业务代码。

应用场景

想要复用一些现有的类,但是接口与复用环境要求不一致,比如入参不同、返回结果结构不能满足需求等。

模式特征

角色 说明 举栗
Interface(目标接口) 客户端期望的接口 SayHello
Adapter(适配器) 完成适配工作的类,实现Interface ClassAdapter、ObjectAdapter
Adaptee(被适配者) 已有的功能类,待适配 Hello

实现方式

  • 类适配器模式:Adapter直接继承Adaptee,并实现Interface
  • 对象适配器模式:Adapter实现Interface,并依赖Adaptee

UML

类适配器模式

类适配器模式类图

对象适配器模式

对象适配器模式类图

代码实现

  • 被适配者:返回英文 “hello adapter”,但是我们的需求是返回中文
public class Hello {
    public String hello(){
        return "hello adapter";
    }
}
  • 目标接口:返回中文的接口
public interface SayHello {
    void sayHelloInChinese();
}
  • 类适配器模式
public class ClassAdapter extends Hello implements SayHello {

    @Override
    public void sayHelloInChinese() {
        String str = super.hello();
        String result = doTranslate(str);
        System.out.println(result);
    }

    private String doTranslate(String str) {
        //具体翻译实现省略
        return "你好,适配器";
    }
}
  • 对象适配器模式
public class ObjectAdapter implements SayHello {

    //依赖Hello
    private Hello hello = new Hello();

    @Override
    public void sayHelloInChinese() {
        String str = hello.hello();
        String result = doTranslate(str);
        System.out.println(result);
    }

    private String doTranslate(String str) {
        //具体翻译实现省略
        return "你好,适配器";
    }
}
  • 客户端测试类
public class Client {
    public static void main(String[] args) {
        //类适配器
        ClassAdapter classAdapter = new ClassAdapter();
        classAdapter.sayHelloInChinese();

        //对象适配器
        ObjectAdapter objectAdapter = new ObjectAdapter();
        objectAdapter.sayHelloInChinese();
    }
}
  • 输出结果
你好,适配器
你好,适配器

优点

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。
  • 增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用。
  • 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。

顺便说一句

其实还有一种缺省适配器模式,其主要功能就是让我们可以按需实现功能。
因为对于一个接口内的方法,有时候我们并不需要实现所有方法,但是一旦我们实现接口,我们的实现类里面就必然列出了接口内的所有方法,即是我们不去实现它。这样会让人很不舒服(代码洁癖患者),而缺省适配器模式可以解决这一尴尬现象,但是我们这里不做介绍(有兴趣的可以自行了解)。
但是在Java8中提供了default关键字,可以实现缺省适配器模式的效果,直接用代码解释吧:

  • 问候接口类
public interface Hello{
    default void sayHelloInChinese(String name){}
    
    default void sayHelloInEnglish(String name){}
}
  • 中文问候实现
public class ChineseHello implements Hello{
    
    @Override
    public void sayHelloInChinese(String name){
        System.out.println("你好:" + name);
    }
}
  • 英文问候实现
public class EnglishHello implements Hello{
    
    @Override
    public void sayHelloInEnglish(String name){
        System.out.println("Hello:" + name);
    }
}
原创文章 67 获赞 31 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u012534326/article/details/102538217