设计模式之适配器模式

概述

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)

这种模式涉及到一个单一的类,该类负责加入独立或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

主要分为三类:类适配器模式、对象的适配器模式、接口的适配器模式

适配器的流程类似如下:需要被适配的->Adapter->最终想要的

特点:

1、可以让任何两个没有关联的类一起运行。

2、提高了类的复用。

3、增加了类的透明度。

4、灵活性好。

注意:适配器不是在详细设计时添加的,主要是解决正在服役的项目的问题。

使用场景

  1. 系统需要使用现有的类,而这些类的接口不符合系统的需要。
  2. 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
  3. 需要一个统一的输出接口,而输入端的类型不可预知。

在实际使用中无需过于拘泥于以下设计模式的例子,可根据实际业务需要进行设计。

电压类适配器示例

场景:充电器例子,需要将220v的电压转换为5v的电压。

需要被适配已有220v电压的类

/**
* 需要适配已有220v电压的类
*/
static class Voltage220 {

public int output220V(){
System.out.println("输出220v电压");
return 220;
}
}

需要的5v的接口

/**
* 需要的5v的接口
/
interface Voltage5 {
/
*
* 需要输出5v电压
*/
int output5V();
}

电压适配器

/**
* 适配器
*/
static class VoltageAdapter extends Voltage220 implements Voltage5 {

@Override
public int output5V() {
// 将输入5v的参数转为220v的获取执行结果
int voltage = output220V();
// 将结果转换为5v需要的返回结果
System.out.println("适配器开始工作,转换电压为5v");
return voltage/44;
}
}

使用

public static void main(String[] args) {
// 创建Voltage5时使用适配器来创建
Voltage5 voltage5 = new VoltageAdapter();
int voltage = voltage5.output5V();
if (voltage==5){
System.out.println("电压适配成功,开始充电");
}else {
System.out.println("电压适配失败,充电器即将爆炸,请马上断开电源");
}
}

类适配器,让Adapter继承需要被适配的的类,在里面对其进行处理;由于Java的单继承机制,其使用成本也增加了;

对象适配器

/**
* 需要的5v的接口
/
interface Voltage5 {
/
*
* 需要输出5v电压
*/
int output5V();
}

/**
* 需要适配已有220v电压的类
*/
static class Voltage220 {

public int output220V(){
System.out.println("输出220v电压");
return 220;
}
}

static class VoltageAdapter implements Voltage5 {

private Voltage220 voltage220;
// 让适配器持有需要适配的对象
public VoltageAdapter(Voltage220 voltage220){
this.voltage220 = voltage220;
}

@Override
public int output5V() {
int voltage = voltage220.output220V();
System.out.println("适配器开始工作,转换电压为5v");
return voltage/44;
}
}

使用

public static void main(String[] args) {
VoltageAdapter voltageAdapter = new VoltageAdapter(new Voltage220());
int voltage = voltageAdapter.output5V();
if (voltage==5){
System.out.println("电压适配成功,开始充电");
}else {
System.out.println("电压适配失败,充电器即将爆炸,请马上断开电源");
}
}

将对象传递给适配器

接口适配器

interface WxPay {

void pay();

void refund();

}

static abstract class WxPayAdapter implements WxPay {
@Override
public void pay(){

}

@Override
public void refund(){

}
}

使用

public static void main(String[] args) {

WxPay wxPay = new WxPay() {
@Override
public void pay() {
System.out.println("支付实现");
}

@Override
public void refund() {
System.out.println("退款实现");
}
};
wxPay.pay();

// 使用适配器后只需要实现我们需要的即可
WxPayAdapter wxPayAdapter = new WxPayAdapter() {
@Override
public void pay() {
System.out.println("支付实现");
}
};
wxPayAdapter.pay();
}

以接口为目标的适配器;这种方式在安卓中非常常见,比如添加相关的监听器,我只需要实现我们需要的即可,对应不需要的无需去实现,简化了代码。

接口升级兼容示例

未使用设计模式时

public class NoAdapterPattern {

public static void main(String[] args) {
MediaPlayerV1 oldObject = new MediaPlayerV1Impl();
MediaPlayerV2 newObject = new MediaPlayerV2Impl();
oldObject.play();
newObject.play();
}

/**
* v1版本接口
*/
public static interface MediaPlayerV1 {

void play();
}

/**
* v1版本接口实现类
*/
public static class MediaPlayerV1Impl implements MediaPlayerV1 {

@Override
public void play() {
System.out.println("播放mp3");
}
}

/**
* v2版本接口
*/
public static interface MediaPlayerV2 {

void play();
}

/**
* v2版本接口实现类
*
*/
public static class MediaPlayerV2Impl implements MediaPlayerV2 {
@Override
public void play() {
System.out.println("播放mp4");
}
}
}

使用类适配器模式

public class AdapterPatter {

public static void main(String[] args) {
// 将v1版本的转换为v2版本的接口
MediaPlayerV2 oldObject = new NewInterfaceAdapter();
MediaPlayerV2 newObject = new MediaPlayerV2Impl();
oldObject.play();
newObject.play();
}

/**
* 定义一个适配器类
*/
public static class NewInterfaceAdapter implements MediaPlayerV2 {

private final MediaPlayerV1 v1;

public NewInterfaceAdapter(){
this.v1 = new MediaPlayerV1Impl();
}

@Override
public void play() {
// 实际调用v1版本的实现
this.v1.play();
}
}

/**
* v1版本接口
*/
public static interface MediaPlayerV1 {

void play();
}

/**
* v1版本接口实现类
*/
public static class MediaPlayerV1Impl implements MediaPlayerV1 {

@Override
public void play() {
System.out.println("播放mp3");
}
}

/**
* v2版本接口
*/
public static interface MediaPlayerV2 {

void play();
}

/**
* v2版本接口实现类
*/
public static class MediaPlayerV2Impl implements MediaPlayerV2 {
@Override
public void play() {
System.out.println("播放mp4");
}
}
}

适配器的新接口方法的实现,全部基于老接口实现类的老方法来实现即可;对于调用方,只要使用适配器来开发即可,就可以通过面向新接口开发,底层使用老接口实现类。

posted @ 2020-09-25 23:03  起岸星辰  阅读(165)  评论(0)    收藏  举报