您现在的位置是:首页 >技术交流 >适配器模式知多少网站首页技术交流
适配器模式知多少
简介适配器模式知多少
目录
目标
熟悉适配器设计模式,了解适配器设计模式的使用场景、具体实现。
概述
一、结构型设计模式
结构型设计模式是设计模式的一种类型。它的关注点在于如何将对象和类组合成更大的结构。较为常见的结构型设计模式如:装饰者设计模式、代理模式、适配器模式、桥接模式、组合模式等。
二、适配器设计模式
旨在解决两个两个接口不兼容的问题。通过适配器将一个类的接口转换成客户期望的另一个接口,从而让两个不兼容的接口协同工作。生活中也有类似的案例:超薄笔记本连接网线需要转接头(相当于适配器),手机充电线接头或耳机接头也会应为型号不兼容手机而使用转接头(相当于适配器)。
优点:
- 实现代码复用。
- 降低系统耦合。
- 不需要修改代码就可以使用新接口。
缺点:
- 该模式需要引入适配器对象,增加了代码复杂度和运行开销。
- 不适用于经常变化的接口,因为接口的变化会导致适配器类需要修改。
三、使用场景
- 系统升级或重构时,旧接口无法满足新需求时。
- 系统集成时,多个接口集成为一个接口时。
- 要将一个类与其他类协同工作,但是其他类的接口不兼时。
四、列举适配器模式在成熟的框架中的应用
- 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");
}
}
输出
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。