【Java 设计模式 · 结构型】适配器模式(Adapter Pattern)

适配器模式是一种结构型设计模式,用于将不同接口的对象协同工作。它允许类或对象的接口转换为客户期望的形式。通过类适配器或对象适配器,适配器模式提供了在不修改原有代码的情况下复用已有组件的能力。例如,在一个汽车控制系统中,适配器模式被用来使控制软件能够灵活地控制警车的警灯闪烁和警笛鸣笛,增加了系统的可扩展性和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结构型模式关注如何将现有类或对象组织一起形成更加强大的结构。

一、概述

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

二、结构

  • Target(目标抽象类):
    定义客户所需接口,可以是抽象类 / 接口、具体类,类适配器只能使用接口。
  • Adapter(适配器类):
    可以调用 另一个接口,作为一个转换器,对Adaptee 和 Target 进行适配。
  • Adaptee(适配者类):
    被适配的角色,定义了一个已经存在、需要适配的接口,包含业务方法。

类适配器:
类适配器
适配者类 Adaptee 没有 request() 方法,而使用者期望该方法,适配者类并无该方法。定义适配器类 Adapter 实现 Target 接口,并继承 适配者类 Adaptee 从而解决该问题。在适配者类的 request() 方法中调用所继承的适配者类 specialRequest() 方法,以达到目的:

public class Adapter extends Adaptee implements Target {
	@Override
	public void request(){
		super.specialRequest();
	}
}

对象适配器:
对象适配器
对象适配器与类适配器类似,不同的点在于:类适配器通过类继承特性,达到目的;而对象适配器则采用 组合 / 聚合方式完成兼容:

public class Adapter extends Target{
	private Adaptee adaptee;		//维持一个对适配者对象的引用
	//构造器:初始化
	public Adapter(Adaptee adaptee){
		this.adaptee = adaptee;
	}
	@Override
	public void request(){
		adaptee.specialRequest();	//转发调用
	}
}

三、举例

我们以 对象适配器 为例,应用至以下场景:

警车在移动过程中伴随警灯闪烁、警笛鸣笛,现在已经实现了 警灯闪烁、警笛鸣笛 的代码,须重用该代码,并使得控制软件具有更好的灵活性、可扩展性。
举例类图

实例代码:

汽车控制类:充当 目标抽象类:

//汽车控制类:负责控制汽车运转
public abstract class CarController {
	//车移动
    public void move(){
        System.out.println("警车移动!");
    }
    //预留方法:闪灯、鸣笛
    public abstract void phonate();
    public abstract void twinkle();
}

警笛类:充当 适配者:

//警笛类:负责警车鸣笛
public class PoliceSound {
	//鸣笛方法
    public void alarmSound(){
        System.out.println("警笛鸣笛!");
    }
}

警灯类:充当 适配者:

//警灯类:负责警灯闪烁
public class PoliceLamp {
	//闪灯方法
    public void alarmLamp(){
        System.out.println("警灯闪烁!");
    }
}

警车 (适配) 类:充当 适配器:

//警车类:适配器类
public class PoliceCar extends CarController{
    private PoliceSound sound;
    private PoliceLamp lamp;

    //无参数构造器:自动初始化
    public PoliceCar() {
        this.sound = new PoliceSound();
        this.lamp = new PoliceLamp();
    }

    //全参数构造器:初始化
    public PoliceCar(PoliceSound sound, PoliceLamp lamp) {
        this.sound = sound;
        this.lamp = lamp;
    }

    @Override
    public void phonate() {
        this.sound.alarmSound();
    }

    @Override
    public void twinkle() {
        this.lamp.alarmLamp();
    }
}

测试代码:

try{
	CarController car;
	car = (CarController) Class.forName("com.simple.PoliceCar").getDeclaredConstructor().newInstance();
	car.move();
	car.phonate();
	car.twinkle();
}catch (Exception e){
	e.printStackTrace();
}

结果

四、特点

☯ 优点

共同优点:

  • 目标者类与适配者类解耦,引入适配器类重用适配者类。
  • 使用适配者类封装业务,可在不影响原有结构的条件下,反复复用该类。
  • 较好的灵活性、扩展性,完全符合开闭原则。

类适配优点:

  • 适配器类是适配者子类,可重写适配者方法,使得适配器更加灵活。

对象适配优点:

  • 一个对象适配器可适配多个适配者,不受单继承体系的影响。
  • 根据里氏转换原则,可适配已适配的适配者子类。

☯ 缺点

类适配缺点:

  • 单继承体系使得适配数量受限
  • 适配者类不能为final类
  • 目标抽象类仅能为接口

对象适配缺点:

  • 该模式下,要在适配器中替换适配者类的某些方法比较麻烦,若需实现,可定义一已重写适配者类方法的子类,并对其进行适配,使得类结构更复杂。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值