适配器模式

结构型模式:用于描述如何将类或对象按某种布局组成更大的结构,GoF 中提供了代理、适配器、桥接、装饰、外观、享元、组合等 7 种结构型模式

它分为类结构型模式对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象

由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性

1. 背景

在现实生活中,经常出现两个对象因接口不兼容而不能在一起工作的实例,这时需要第三者进行适配。例如,讲中文的人同讲英文的人对话时需要一个翻译,用直流电的笔记本电脑接交流电源时需要一个电源适配器,用计算机访问照相机的 SD 内存卡时需要一个读卡器等

在软件设计中也可能出现:需要开发的具有某种业务功能的组件在现有的组件库中已经存在,但它们与当前系统的接口规范不兼容,如果重新开发这些组件成本又很高,这时用适配器模式能很好地解决这些问题

2. 定义

适配器模式(Adapter)的定义如下: 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作

具体的使用场景如下:

  • 已经存在的类的接口不符合我们的需求;

  • 创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作;

  • 在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类
    在这里插入图片描述
    目标(Target)接口: 当前系统业务所期待的接口,它可以是抽象类或接口。
    适配者(Adaptee)类: 它是被访问和适配的现存组件库中的组件接口。
    适配器(Adapter)类: 它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者

优点

  • 客户端通过适配器可以透明地调用目标接口。
  • 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
  • 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。

缺点

  • 对类适配器来说,更换适配器的实现过程比较复杂

3. 适配器模式

适配器模式分为类结构型模式对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些(网上有的说还有接口模式,好像不重要)

3.1 类适配器

Adapter类通过继承Adaptee类,实现Target接口,完成AdapteeTarget的转换

以充电器的例子来说,充电器本身是Adapter,220v的交流电是Adaptee,我们的目标则是被转换后的5v的直流电
在这里插入图片描述

package adapter;
//目标接口
interface Target{
    public void request();
}
//被适配者
class Adaptee{
    public void specificRequest(){       
        System.out.println("适配者中的业务代码被调用!");
    }
}
//类适配器类
class ClassAdapter extends Adaptee implements Target{
    public void request(){
        specificRequest();
    }
}
//客户端代码
public class ClassAdapterTest{
    public static void main(String[] args){
        System.out.println("类适配器模式测试:");
        Target target = new ClassAdapter();
        target.request();
    }
}

缺点:
① Java是单继承机制,所以类适配器要求继承adaptee类这一点算是一个缺点,因为要求target必须是一个接口,有一定的局限性;

比如说我们现在有一个需求:我们有一个能从数据库中抽取文本的工具类TextTool,一个抽取图片的工具类ImageTool;现在我们又需要一个抽取合成富文本的工具类(既有文字又有图片),而抽取文字和图片的功能前面都实现了,那我们就可以使用适配器模式去继承TextToolImageTool,但是由于Java的单继承机制,这显然是办不到的
在这里插入图片描述

adaptee类的方法在Adapter中完全暴露了出来,也增加了使用成本

优点:
由于其继承adaptee,所以可以根据需求重写adaptee类的方法,使adapter的灵活性增强

3.2 对象适配器

上面的问题主要就出在继承上,而根据合成复用规则在系统中尽量使用关联关系来替代继承关系,于是就有了对象适配器

对象适配器的基本思路和类的适配器模式相同,只是将Adapter类做修改,不是继承Adaptee类,而是持有Adaptee的实例,以解决兼容性问题,即持有Adaptee,实现target接口,完成adapteetarget的转换

在这里插入图片描述

package adapter;
//目标接口
interface Target{
    public void request();
}
//被适配者
class Adaptee{
    public void specificRequest(){       
        System.out.println("适配者中的业务代码被调用!");
    }
}

//对象适配器类
class ObjectAdapter implements Target{
    private Adaptee adaptee;
    public ObjectAdapter(Adaptee adaptee){
        this.adaptee=adaptee;
    }
    public void request(){
        adaptee.specificRequest();
    }
}

//客户端代码
public class ObjectAdapterTest{
    public static void main(String[] args){
        System.out.println("对象适配器模式测试:");
        Adaptee adaptee = new Adaptee();
        Target target = new ObjectAdapter(adaptee);
        target.request();
    }
}

实际我认为不就是对原有代码的一种巧妙复用么…

4. SprigMVC中的适配器模式

SprigMVC中的适配器模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值