当前位置: 代码迷 >> 综合 >> 设计模式学习(四)——结构型模式之“适配器模式(adapter )”
  详细解决方案

设计模式学习(四)——结构型模式之“适配器模式(adapter )”

热度:70   发布时间:2024-01-03 10:16:11.0

常见的结构型模式:

  • 适配器模式——把一个类的接口变成客户端所期待的另一种接口
  • 装饰模式——又名包装模式,以对客户端透明的方式扩展对象的功能,是继承关系的替代方案
  • 代理模式——开闭原则的直接支持
  • 桥接模式
  • 组合模式
  • 外观模式

什么是结构型模式:

  • 描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以将简单的积木组合成复杂的、功能强大的结构

一、适配器模式介绍

例如SpringMVC中常用适配器,跟接口有关系

1.1、适配器模式定义

当你想使用一个已经存在的类,而他的接口不符合你的需求,或者想创建一个可重用的类。可以用适配器模式,它与装饰模式都有“包装”的功能

1.2、适配器分类

类适配器、对象适配、接口适配方式。

类适配器方式采用继承方式;对象适配方式使用构造函数传递

1.3、类适配器和对象适配器区别

  • 类适配器:对象继承的方式,静态的定义
  • 对象适配器:依赖于对象的组合,都是采用对象组合的方式

1.4、适配器的使用地方

(1)I/O库中适配器的使用

OutputStreamWriter:是Writer的子类,将输出的字符流变为字节流,即:将一个字符流的输出对象变为字节流的输出对象。

InputStreamReader:是Reader的子类,将输入的字节流变为字符流,即:将一个字节流的输入对象变为字符流的输入对象。

(2)Spring框架中适配器的使用

SpringAOP 里需要将每个 Advice(通知)都封装成对应的拦截器类型,返回给容器,所以需要使用适配器模式对Advice 进行转换

(3)第三方技术

在使用第三方的类库,或者说第三方的API的时候,我们通过适配器转换来满足现有系统的使用需求

(4)新旧系统集成

我们的旧系统与新系统进行集成的时候,我们发现旧系统的数据无法满足新系统的需求,那么这个时候,我们可能需要适配器,完成调用需求

(5)数据库同步

我们在使用不同数据库之间进行数据同步

1.5、适配器的优点缺点

优点:

  • 让任何两个没有关联的类一起运行;
  • 提高了类的复用;
  • 增加了类的透明度,客户端只关注结果。

缺点:

  • 过多使用会导致系统凌乱,追溯困难

 

二、代码示例

2.1、类适配器

示例1:日本电饭煲电源接口标准是110V电压,而中国标准电压接口是220V,所以要想在中国用日本电饭煲,需要一个电源转换器。

//定义日本和中国两种接口及其实现
//一、先定义日本220V电源接口和实现
//1.1、日本110V电源接口
public interface JP110VInterface {public void connect();
}
//1.2、日本110V电源接口实现
public class JP110VInterfaceImpl implements JP110VInterface {@Overridepublic void connect() {System.out.println("日本110V,接通电源,开始工作..");}
}//二、再定义中国220V电源接口和实现
public interface CN220VInterface {public void connect();
}
public class CN220VInterfaceImpl implements CN220VInterface {@Overridepublic void connect() {System.out.println("中国220V,接通电源,开始工作");}
}
//定义一个电压适配器
//三、要想在中国使用日本电饭煲,需要把电饭煲110v的电源接口适配成我们220V的电源接口,这就需要一个电源适配器
public class ElectricCooker {private JP110VInterface jp110VInterface;//日本电饭煲ElectricCooker(JP110VInterface jp110VInterface){this.jp110VInterface=jp110VInterface;}public void cook(){jp110VInterface.connect();System.out.println("开始做饭了..");}
}
public class PowerAdaptor implements JP110VInterface {private CN220VInterface cn220VInterface;//中国电饭煲public PowerAdaptor(CN220VInterface cn220VInterface) {this.cn220VInterface = cn220VInterface;}@Overridepublic void connect() {cn220VInterface.connect();}
}
//四、测试开始运行
public class AdaptorTest {public static void main(String[] args) {//220V电源接口CN220VInterface cn220VInterface = new CN220VInterfaceImpl();//适配器接口PowerAdaptor powerAdaptor = new PowerAdaptor(cn220VInterface);// 电饭煲ElectricCooker cooker = new ElectricCooker(powerAdaptor);cooker.cook();//使用了适配器,在220V的环境可以工作了。}
}

示例2:想用小米4数据线链接小米5手机,使用转换器。

//1.定义M4DataLine 代表USB ——————小米4数据线
class M4DataLine {public void connection() {System.out.println("使用小米4数据线连接...");}
}
//2.定义客户端使用的接口,与业务相关
interface Target {void connection();
}
class M5DataLine implements Target {@Overridepublic void connection() {System.out.println("使用小米5数据线连接...");}
}
//3.创建适配器类,继承了被适配类,同时实现标准接口——————转换器
class M5DataLineAdapter extends M4DataLine implements Target {@Overridepublic void connection() {System.out.println("插入 type-c 转接头");super.connection();}
}
//4.客户端代码,测试
public class AdapterMain {public static void main(String[] args) {Target target = new M5DataLine();target.connection();Target adapter = new M5DataLineAdapter();adapter.connection();}
}
//5.结果
使用小米5数据线连接...
插入 type-c 转接头
使用小米4数据线连接...

2.2、对象适配器

创建适配器类,实现标准接口,将这个调用委托给实现新接口的对象来处理

略....