面试官:啥是适配器模式?

2021-12-29 12:27:34 浏览数 (1)

  • 1. 结构型模式概述
  • 2. 适配器模式概述
  • 3. 适配器模式的结构与实现
  • 4. 适配器模式的应用实例
  • 5. 缺省适配器模式
  • 双向适配器
  • 6. 适配器模式的优缺点与适用环境

“Github:https://github.com/nateshao/design-demo/tree/main/JavaDesignPatterns

1. 结构型模式概述

  • 结构型模式(Structural Pattern)关注如何将现有类或对象组织在一起形成更加强大的结构
  • 不同的结构型模式从不同的角度组合类或对象,它们在尽可能满足各种面向对象设计原则的同时为类或对象的组合提供一系列巧妙的解决方案

类结构型模式

“关心类的组合,由多个类组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系

对象结构型模式

“关心类与对象的组合,通过关联关系,在一个类中定义另一个类的实例对象,然后通过该对象调用相应的方法

结构型模式一览表

2. 适配器模式概述

电源适配器

分析

现实生活:

  • 不兼容:生活用电220V <- ->笔记电脑20V
  • 引入 AC Adapter(交流电适配器)

软件开发:

  • 存在不兼容的结构,例如方法名不一致
  • 引入适配器模式

适配器模式的定义

适配器模式:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作

对象结构型模式 / 类结构型模式

  1. 别名为包装器(Wrapper)模式
  2. 定义中所提及的接口是指广义的接口,它可以表示一个方法或者方法的集合

适配器模式的结构(类适配器)

适配器模式的结构(对象适配器)

适配器模式包含以下3个角色:

  • Target(目标抽象类)
  • Adapter(适配器类)
  • Adaptee(适配者类)

3. 适配器模式的结构与实现

典型的类适配器代码:

代码语言:javascript复制
public class Adapter extends Adaptee implements Target {
    public void request() {
        super.specificRequest();
    }
}

典型的对象适配器代码:

代码语言:javascript复制
public class Adapter extends Target {
    private Adaptee adaptee; //维持一个对适配者对象的引用
 
    public Adapter(Adaptee adaptee) {
        this.adaptee=adaptee;
    }
 
    public void request() {
        adaptee.specificRequest(); //转发调用
    }
}

4. 适配器模式的应用实例

实例说明:

某公司欲开发一款儿童玩具汽车,为了更好地吸引小朋友的注意力,该玩具汽车在移动过程中伴随着灯光闪烁和声音提示。在该公司以往的产品中已经实现了控制灯光闪烁(例如警灯闪烁)和声音提示(例如警笛音效)的程序,为了重用先前的代码并且使得汽车控制软件具有更好的灵活性和扩展性,现使用适配器模式设计该玩具汽车控制软件。

实例类图:

实例代码

  1. CarController:汽车控制类,充当目标抽象类
  2. PoliceSound:警笛类,充当适配者
  3. PoliceLamp:警灯类,充当适配者
  4. PoliceCarAdapter:警车适配器,充当适配器
  5. Client:客户端测试类
  6. XMLUtil:工具类

结果及分析

将具体适配器类的类名存储在配置文件中

扩展方便

代码语言:javascript复制
<?xml version="1.0"?>
<config>
 <className>designpatterns.adapter.PoliceCarAdapter</className>
</config>

5. 缺省适配器模式

“定义:缺省适配器模式(Default Adapter Pattern):当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用一个接口中的所有方法的情况,又称为单接口适配器模式。

实现:

缺省适配器类的典型代码片段:

代码语言:javascript复制
public abstract class AbstractServiceClass implements ServiceInterface {
    public void serviceMethod1() {  }  //空方法
    public void serviceMethod2() {  }  //空方法
    public void serviceMethod3() {  }  //空方法
}

双向适配器

结构

实现:双向适配器典型代码片段

代码语言:javascript复制
public class Adapter implements Target,Adaptee {
    private Target target;
    private Adaptee adaptee;
 
    public Adapter(Target target) {
        this.target = target;
    }
 
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
 
    public void request() {
        adaptee.specificRequest();
    }
 
    public void specificRequest() {
        target.request();
    }
}

6. 适配器模式的优缺点与适用环境

模式优点

  1. 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构
  2. 增加了类的透明性和复用性,提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用
  3. 灵活性和扩展性非常好
  4. 类适配器模式:置换一些适配者的方法很方便
  5. 对象适配器模式:可以把多个不同的适配者适配到同一个目标,还可以适配一个适配者的子类

模式缺点

  1. 类适配器模式: (1) 一次最多只能适配一个适配者类,不能同时适配多个适配者; (2) 适配者类不能为最终类; (3) 目标抽象类只能为接口,不能为类
  2. 对象适配器模式:在适配器中置换适配者类的某些方法比较麻烦

模式适用环境

  1. 系统需要使用一些现有的类,而这些类的接口不符合系统的需要,甚至没有这些类的源代码
  2. 创建一个可以重复使用的类,用于和一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作

0 人点赞