【Java教程】Day20-06 设计模式:结构型模式——适配器模式

一、适配器模式概述

适配器模式(Adapter Pattern)是一种结构型设计模式,它的作用是将一个类的接口转换成客户期望的另一个接口,从而解决接口不兼容导致无法协同工作的问题。适配器模式常用于需要将不同接口的类进行组合、集成时,尤其是在老旧系统与新系统之间的接口适配中非常常见。

举个例子,假如你要去美国旅游,你的电器设备无法直接插入美国的插座,因为插座类型不同,此时你需要一个适配器将中国的插头转换为美国插座。程序设计中的适配器模式正是用来解决接口不兼容的问题。

二、适配器模式的工作原理

2.1 适配器模式示例

假设我们有一个实现了Callable接口的Task类:

javapublic class Task implements Callable<Long> {    private long num;    public Task(long num) {        this.num = num;    }    public Long call() throws Exception {        long result = 0;        for (long n = 1; n <= this.num; n++) {            result += n;        }        System.out.println("Result: " + result);        return result;    }}

 

现在,我们希望通过线程来执行这个任务。可是,Thread类接收的是Runnable接口,而不是Callable接口,因此会报错:

javaCallable<Long> callable = new Task(123450000L);Thread thread = new Thread(callable); // 编译错误thread.start();

 

这个问题的解决方法是使用适配器模式。我们不直接修改Task类,而是创建一个适配器,将Callable接口适配为Runnable接口。

2.2 创建适配器

下面是适配器的实现:我们编写一个RunnableAdapter类,实现了Runnable接口,并内部持有一个Callable接口的实例:

javapublic class RunnableAdapter implements Runnable {    private Callable<?> callable;    public RunnableAdapter(Callable<?> callable) {        this.callable = callable;    }    @Override    public void run() {        try {            callable.call();        } catch (Exception e) {            throw new RuntimeException(e);        }    }}

 

这里,RunnableAdapter类实现了Runnable接口,并通过call()方法将Callable接口的调用转发给内部的callable实例。这样,我们就可以通过适配器将Task类适配为Runnable,从而能够正常编译:

javaCallable<Long> callable = new Task(123450000L);Thread thread = new Thread(new RunnableAdapter(callable));thread.start();

 

三、适配器模式的实现步骤

编写适配器模式时,可以遵循以下步骤:

  1. 实现目标接口:首先,定义我们需要适配的目标接口,在本例中是Runnable接口。

  2. 持有待转换接口的引用:适配器类内部通过字段持有一个待适配的接口实例,通常是Callable

  3. 在目标接口方法中调用待适配接口的方法:适配器类的目标方法(如run())内部调用待适配接口的原有方法(如call())。

 

通过这样的方式,我们就能使得不兼容的接口能够协同工作。

四、适配器模式在Java中的应用

4.1 数组转集合的适配

在Java标准库中,Arrays.asList()方法将数组转换为List接口,就实现了数组与集合类型之间的适配:

javaString[] exist = new String[] {"Good", "morning", "Bob", "and", "Alice"};Set<String> set = new HashSet<>(Arrays.asList(exist));

 

在这里,Arrays.asList()充当了适配器,将String[]类型转换成了List<String>类型。

4.2 输入输出流的适配

在I/O操作中,适配器模式也有广泛应用。比如,我们有一个InputStream对象,而需要将其传入一个readText(Reader)方法中:

javaInputStream input = Files.newInputStream(Paths.get("/path/to/file"));Reader reader = new InputStreamReader(input, "UTF-8");readText(reader);

 

在这段代码中,InputStreamReader就是一个适配器,它将InputStream转换成了Reader。类似地,OutputStreamWriterOutputStream适配为Writer

4.3 适配器解决类间不兼容问题

有时候我们需要将一个接口适配为具体的类。例如,如果我们需要FileReader,但手头只有InputStream,我们就需要适配器:

javaFileReader reader = new InputStreamReader(input, "UTF-8"); // 编译错误

 

InputStreamReader可以将InputStream适配为Reader,但如果需要FileReader,就需要更多的适配工作,可能需要创建一个新的适配器。此时,抽象编程原则的优势显现出来,持有抽象接口使得接口组合和适配变得更加灵活。

五、练习:使用适配器模式将Callable适配为Runnable

  1. 实现一个适配器,将Callable接口适配为Runnable接口。

  2. 编写一个测试类,使用RunnableAdapter来启动一个线程执行Task类。

示例代码:

javapublic class Main {    public static void main(String[] args) {        Callable<Long> callable = new Task(1000L);        Thread thread = new Thread(new RunnableAdapter(callable));        thread.start();    }}

 

六、小结

适配器模式(Adapter Pattern)是一种结构型设计模式,主要用于将一个类的接口转换成客户期望的另一个接口,从而解决类之间接口不兼容的问题。通过适配器模式,我们可以轻松地实现不同接口之间的转换,从而让不兼容的类能够一起工作。

适配器模式的实现通常包括:

  1. 实现目标接口。

  2. 持有待适配接口的实例。

  3. 将目标接口方法的调用委托给待适配接口。

 

适配器模式在Java标准库中有广泛应用,如Arrays.asList()方法、InputStreamReader等。

适配器模式非常适合于不同接口或类之间的衔接,可以提高代码的灵活性与可扩展性。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值