您现在的位置是:首页 >技术交流 >适配器模式知多少网站首页技术交流

适配器模式知多少

我的身前一尺是我的世界 2024-06-17 11:26:31
简介适配器模式知多少

目录

目标

概述

实战


目标

熟悉适配器设计模式,了解适配器设计模式的使用场景、具体实现。


概述

一、结构型设计模式

结构型设计模式是设计模式的一种类型。它的关注点在于如何将对象和类组合成更大的结构。较为常见的结构型设计模式如:装饰者设计模式、代理模式、适配器模式、桥接模式、组合模式等。

二、适配器设计模式

旨在解决两个两个接口不兼容的问题。通过适配器将一个类的接口转换成客户期望的另一个接口,从而让两个不兼容的接口协同工作。生活中也有类似的案例:超薄笔记本连接网线需要转接头(相当于适配器),手机充电线接头或耳机接头也会应为型号不兼容手机而使用转接头(相当于适配器)。

优点:

  • 实现代码复用。
  • 降低系统耦合。
  • 不需要修改代码就可以使用新接口。

缺点:

  • 该模式需要引入适配器对象,增加了代码复杂度和运行开销。
  • 不适用于经常变化的接口,因为接口的变化会导致适配器类需要修改。

三、使用场景

  • 系统升级或重构时,旧接口无法满足新需求时。
  • 系统集成时,多个接口集成为一个接口时。
  • 要将一个类与其他类协同工作,但是其他类的接口不兼时。

四、列举适配器模式在成熟的框架中的应用

  • Hibernate中的JDBC适配器。
  • Netty的ChannelHandler接口和 ChannelHandlerAdapter类实现了适配器模式,通过适配器模式,可以灵活的实现自定义的ChannelHandler。
  • MyBatis中的TypeHandler是一个接口,用于将Java对象转换成JDBC可用的类型。当我们自定义TypeHandler来处理一些特殊的类型。这时候就可以使用适配器模式。
  • Spring MVC中默认的处理器映射器只能处理标准的HTTP请求,无法处理自定义的请求。为了解决这个问题,Spring MVC提供了适配器来将自定义的Controller适配成标准的处理器。

五、适配器模式和装饰者模式的区别

装饰者模式适配器模式
目的在运行时根据业务,动态地给对象新增额外功能。强调增强性。把一个接口转换成另一个接口。强调兼容性。
封装装饰者封装被装饰者,比如:在糖、盐和咖啡这三者中,咖啡是被装饰者,糖和盐是装饰者。适配器封装的是另一个对象的接口,用于转换接口。
实现方式通过装饰者和被装饰者之间的组合实现。通过对象适配器和类适配器实现。

实战

需求

水果供应商公司提供苹果和桔子,它们有各自的包装盒。但是苹果的包装盒用完了,桔子包装盒还有剩余。为了避免浪费,需要把剩余的桔子包装盒转换成适合苹果包装盒的标准。

苹果包装盒和桔子包装盒接口

package com.ctx.adapter;

/**
 * 苹果包装盒接口(默认只能包装苹果)
 */
public interface AppleBox {
    public void pack(String type);
}
package com.ctx.adapter;

/**
 * 桔子包装盒接口(默认只能包装桔子)
 */
public interface OrangeBox {
    public void pack(String type);
}

桔子包装盒适配器类

package com.ctx.adapter;

import com.ctx.adapter.impl.AppleBoxImpl;

/**
 * 桔子包装盒适配器类
 */
public class OrangeBoxAdapter implements OrangeBox {
    AppleBoxImpl appleBoxImpl;
    public OrangeBoxAdapter(String type){
        if(type.equalsIgnoreCase("apple") ){
            appleBoxImpl =new AppleBoxImpl();
        }
    }

    @Override
    public void pack(String type) {
        if(type.equalsIgnoreCase("apple")){
            appleBoxImpl.pack(type);
        }
    }
}

苹果包装盒和桔子包装盒实现类

package com.ctx.adapter.impl;

import com.ctx.adapter.AppleBox;

public class AppleBoxImpl implements AppleBox {
    /**
     * 包装方法
     * @param type
     */
    @Override
    public void pack(String type) {
        if(type.equalsIgnoreCase("apple")){
            System.out.println("包装盒包装:苹果");
        }
    }
}
package com.ctx.adapter.impl;

import com.ctx.adapter.OrangeBoxAdapter;
import com.ctx.adapter.OrangeBox;

public class OrangeBoxImpl implements OrangeBox {
    OrangeBoxAdapter orangeBoxAdapter;
    /**
     * 包装方法
     * @param type
     */
    @Override
    public void pack(String type) {
        if(type.equalsIgnoreCase("orange")){
            System.out.println("包装盒包装:桔子");
        }
        //OrangeAdapter提供了包装苹果的支持
        else if(type.equalsIgnoreCase("apple") ){
            orangeBoxAdapter = new OrangeBoxAdapter(type);
            orangeBoxAdapter.pack(type);
        }
    }
}

测试调用

package com.ctx.adapter;

import com.ctx.adapter.impl.OrangeBoxImpl;

public class Test {
    public static void main(String[] args) {
        OrangeBoxImpl orangeBox = new OrangeBoxImpl();
        orangeBox.pack("orange");
        orangeBox.pack("apple");
    }
}

输出 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。