Java设计模式之适配器模式

适配器模式是一种结构型设计模式,用于将一个类的接口转换成客户端所期望的另一个接口。这种模式通常用于解决接口不兼容的情况,使得原本因接口不匹配而无法在一起工作的类可以协同工作。

适配器模式的作用主要包括以下几个方面:

1.接口转换:适配器模式主要用于解决接口不兼容的情况。当系统中的一个组件提供的接口与另一个组件所期望的接口不匹配时,可以使用适配器模式将其转换为目标接口,使得两者能够协同工作。

2.复用现有功能:适配器模式可以复用现有的功能,无需修改原有代码。通过适配器模式,可以将现有的类或接口无缝地集成到系统中,而无需对其进行修改。

3.解耦合:适配器模式可以降低系统各个组件之间的耦合度。通过引入适配器,使得系统中的各个组件之间的依赖关系变得松散,从而提高系统的灵活性和可维护性。

4.平滑过渡:适配器模式可以实现对旧版本接口的平滑过渡。当系统需要升级或替换某个组件时,可以使用适配器模式适配新旧接口,使得系统能够平稳过渡,避免对已有代码的大规模修改。

总的来说,适配器模式可以帮助我们在系统中集成现有的组件,并使它们与其他组件协同工作,同时保持代码的灵活性和可维护性

不过因为适配器模式不符合开闭原则,而且会导致系统更加复杂导致设计混乱,在日常使用中除非万不得已,否则一般不建议使用!
虽然不建议使用,但是不代表就不能用,所以我们还是需要了解一下什么是适配器模式

适配器模式可以通过不同的实现方式来实现,常见的实现方式包括:

1.类适配器模式:通过继承实现适配器。适配器类继承目标接口,并持有被适配的类的实例。这种方式要求适配器类必须是具体类,无法适配接口。

2.对象适配器模式:通过组合实现适配器。适配器类持有被适配的类的实例,并实现目标接口。这种方式可以适配接口或具体类。

3.接口适配器模式:也称为缺省适配器模式。当目标接口中包含很多方法,而我们只需要实现其中的一部分方法时,可以先提供一个抽象类实现目标接口,然后具体的适配器类只需要覆盖其中需要的方法即可。

这些实现方式各有优缺点,选择哪种实现方式取决于具体的需求和设计考量。

类适配器模式

类适配器模式是一种适配器模式的实现方式之一,它通过继承来实现适配器。在类适配器模式中,适配器类同时继承了目标接口(或抽象类)和被适配的类,从而实现了对目标接口的适配。

具体来说,类适配器模式通常包含以下几个角色:

1.目标接口(Target):定义客户端使用的接口,客户端通过目标接口与适配器进行交互。

2.适配器(Adapter):适配器类是类适配器模式的核心,它同时继承了目标接口和被适配的类。适配器类负责将被适配的类的接口转换为目标接口,从而使得被适配的类可以在客户端被使用。

3.被适配的类(Adaptee):被适配的类是现有的类或接口,其接口与目标接口不兼容,需要通过适配器进行转换。

上代码
首先我们定义一个中国插座

// 目标接口:中国插座
public interface CNSocket {
    void plugIn();
}

但是我们只有一个英国插头

// 被适配的类:英国插头
public class UKPlug {
    public void plugInUK() {
        System.out.println("英国插头插入");
    }
}

所以为了能让这个英国插头插入中国插座中,我们需要一个适配器类

public class UKToCNSocketAdapter extends UKPlug implements CNSocket {
    @Override
    public void plugIn() {
        plugInUK();
        System.out.println("通过适配器,英国插头已适配为中国插座!");
    }
}

然后测试一下

public class Test {

    public static void main(String[] args) {
        // 创建适配器,将英国插头适配为中国插座
        CNSocket chinaSocket = new UKToCNSocketAdapter();
        // 将适配后的插头插入中国插座
        chinaSocket.plugIn();
    }
}

看下结果

在这里插入图片描述

类适配器模式的实现方式相对简单,但也有一些限制。由于Java不支持多重继承,因此在使用类适配器模式时,适配器只能适配一个具体的类,无法同时适配多个类。

对象适配器模式
对象适配器模式与类适配器模式不同的是,对象适配器模式使用组合而不是继承来实现适配器。在对象适配器模式中,适配器类持有被适配的类的实例,并实现目标接口,通过委托调用被适配类的方法来完成适配。

具体来说,对象适配器模式通常包含以下几个角色:

1.目标接口(Target):定义客户端使用的接口,客户端通过目标接口与适配器进行交互。

2.适配器(Adapter):适配器类持有被适配的类的实例,并实现目标接口。适配器类负责将被适配的类的接口转换为目标接口,从而使得被适配的类可以在客户端被使用。

3.被适配的类(Adaptee):被适配的类是现有的类或接口,其接口与目标接口不兼容,需要通过适配器进行转换。

对象适配器模式相比于类适配器模式,具有更大的灵活性,因为它使用组合来实现适配器,使得适配器可以适配多个类,而不受单一继承的限制。此外,对象适配器模式还可以适配不可继承的类或接口。

上代码
一样的还是一个中国插座

// 目标接口:中国插座
public interface CNSocket {
    void plugIn();
}

一个英国插头

// 被适配的类:英国插头
public class UKPlug {
    public void plugInUK() {
        System.out.println("英国插头插入");
    }
}

然后适配器类
可以发现这里就有区别了,不再是继承而是直接持有目标实例

public class UKToCNSocketAdapter implements CNSocket {

    private UKPlug ukPlug;

    public UKToCNSocketAdapter(UKPlug ukPlug) {
        this.ukPlug = ukPlug;
    }
    @Override
    public void plugIn() {
        ukPlug.plugInUK();
        System.out.println("通过适配器,英国插头已适配为中国插座!");
    }
}

测试一下

public class Test {

    public static void main(String[] args) {
        // 创建被适配的类实例
        UKPlug ukPlug = new UKPlug();
        // 创建适配器,将英国插头适配为中国插座
        CNSocket cnSocket = new UKToCNSocketAdapter(ukPlug);
        // 将适配后的插头插入中国插座
        cnSocket.plugIn();
    }
}

一样的结果

在这里插入图片描述

在这个示例中,通过持有UKPlug 类的实例,并实现了目标接口的方式,适配器类可以通过组合适配多个被适配的类,具有更大的灵活性。

接口适配器模式
接口适配器模式也称为缺省适配器模式,是适配器模式的一种变体。它用于解决目标接口中包含很多方法,而客户端只需要实现其中的一部分方法的情况。

接口适配器模式主要由以下几个组件构成:

1.目标接口(Target):定义客户端使用的接口,可能包含多个方法。

2.缺省适配器(DefaultAdapter):提供了目标接口的所有方法的默认实现。这个缺省适配器通常是一个抽象类,实现了目标接口中的所有方法,但这些方法的具体实现为空。

3.具体适配器(Concrete Adapter):客户端根据需要继承缺省适配器,并覆盖其中需要的方法,实现自己的业务逻辑。

通过使用接口适配器模式,客户端只需要关注自己关心的方法,而无需实现接口中的所有方法,从而简化了代码实现。

直接上代码
首先是我们的目标接口,它有多个方法

// 目标接口
interface Target {
    void method1();
    void method2();
    void method3();
}

然后我们定义一个缺省适配器

// 缺省适配器
abstract class DefaultAdapter implements Target {
    @Override
    public void method1() {
        // 默认实现为空
    }

    @Override
    public void method2() {
        // 默认实现为空
    }

    @Override
    public void method3() {
        // 默认实现为空
    }
}

然后我们再来写一个具体的实现类,它只需要实现我们需要的方法

// 具体适配器
class ConcreteAdapter extends DefaultAdapter {
    @Override
    public void method2() {
        System.out.println("ConcreteAdapter: 实现了method2");
    }
}

测试一下

public class Test {

    public static void main(String[] args) {
        Target adapter = new ConcreteAdapter();
        adapter.method2(); // 调用具体适配器的方法
    }
}

运行结果

在这里插入图片描述

在接口适配器模式中,首先定义一个抽象类实现目标接口,并提供了这个接口的所有方法的默认实现。然后客户端只需要继承这个抽象类,并覆盖其中需要的方法即可,无需实现接口中的所有方法,从而避免了不必要的代码实现。通过使用接口适配器模式,客户端只需要关注自己关心的方法,而无需实现接口中的所有方法,从而简化了代码实现。

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子非衣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值