文档章节

设计模式-适配器模式

请把小熊还给我_m
 请把小熊还给我_m
发布于 01/11 20:02
字数 1855
阅读 248
收藏 0

3 月,跳不动了?>>>

一、简介

适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。

适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

在适配器模式中,我们通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。

根据适配器类与适配者类的关系不同,适配器模式可分为对象适配器和类适配器两种
    在对象适配器模式中,适配器与适配者之间是关联关系;
    在类适配器模式中,适配器与适配者之间是继承(或实现)关系。

二、角色

Target(目标抽象类):目标抽象类定义客户所需接口,可以是一个抽象类或接口,也可以是具体类。

Adapter(适配器类):适配器可以调用另一个接口,作为一个转换器,对适配者和目标类进行适配,适配器类是适配器模式的核心,在对象适配器中,它通过继承目标类并关联一个适配者对象使二者产生联系。

Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下可能没有适配者类的源代码。

适配器的优点:
1、将目标类和适配者类解耦
2、增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性
3、灵活性和扩展性都非常好,符合开闭原则

缺省适配器模式(Default Adapter Pattern):当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用一个接口中的所有方法的情况,又称为单接口适配器模式。缺省适配器模式是适配器模式的一种变体,其应用也较为广泛。在JDK类库的事件处理包java.awt.event中广泛使用了缺省适配器模式,如WindowAdapter、KeyAdapter、MouseAdapter等。

三、适配器实现

适配器模式将一个接口转为另外一个接口。它有三种实现方式:

  (1)当希望将一个类转换为满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
  (2)当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个适配器类,持有适配者类的一个实例,在适配器类的方法中,调用<适配者>实例的方法就行。 
     (3)当不希望实现一个接口中所有的方法时,可以创建一个抽象类Adapter ,实现所有方法,我们写别的类的时候,继承抽象类即可。

1、类适配器

适配者类:

public class Adaptee {
    public void adapteeRequest() {
        System.out.println("被适配者的方法");
    }
}

目标抽象类:

public interface Target {
    void request();
}

适配器类:继承适配者类,实现目标抽象类

public class Adapter extends Adaptee implements Target{
    @Override
    public void request() {
        //...一些操作...
        super.adapteeRequest();
        //...一些操作...
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
     
        Target adapterTarget = new Adapter();
        adapterTarget.request();
        //这样我们即可在新接口 Target 中适配旧的接口或类
    }
}

类适配器的优点:由于适配器类是适配者类的子类,因此可以再适配器类中置换一些适配者的方法,使得适配器的灵活性更强。

类适配器的缺点:对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为接口,不能为类,其使用有一定的局限性,不能将一个适配者类和他的子类同时适配到目标接口。

2、对象适配器

对象适配器与类适配器不同之处在于,类适配器通过继承来完成适配,对象适配器则是通过关联来完成。
这里稍微修改一下 Adapter 类即可将转变为对象适配器

public class Adapter implements Target{
    // 注意这里的 适配器 是将 适配者 作为一个成员属性,而不是继承它
    private Adaptee adaptee = new Adaptee();

    @Override
    public void request() {
        //...
        adaptee.adapteeRequest();
        //...
    }
}

对象适配器的优点:把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和他的子类都适配到目标接口。

对象适配器的缺点:与类适配器模式相比,要想置换适配者类的方法就不容易。

3、接口适配器:借助抽象类来实现适配器功能

目标接口:

public interface Target {
    
    void typec();
    void typec2vga();
    void typec2hdmi();
}

适配器抽象类:

/**
 * 定义一个抽象类
 *
 */
public abstract class Adapter implements Target{

    public void typec() { }
    
    public void typec2vga() { }
    
    public void typec2hdmi() { }
}

适配器实现类:

public class VgaAdapter extends Adapter{
    
    public void typec() {
        System.out.println("信息从Typec口的手机输出。");
    }
    
    public void typec2vga() {
        System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");
        System.out.println("信息已转换成VGA接口,显示屏可以对接。");
    }
}

测试类:

package com.jstao.adapter;

/**
 * 定义一个显示屏
 * 与适配器对接
 * @author jstao
 *
 */
public class Screen {
    public static void main(String[] args) {
       
        System.out.println("-------------某一个适配器------------");
        VgaAdapter vgaAdapter = new VgaAdapter();
        vgaAdapter.typec();
        vgaAdapter.typec2vga();//适配器将typec转换成vga
        System.out.println("显示屏对接适配器,手机成功投影到显示屏!");
    }
}

四、应用

1、spring MVC中的适配器模式
Spring MVC中的适配器模式主要用于执行目标 Controller 中的请求处理方法。
在Spring MVC中,DispatcherServlet 作为用户,HandlerAdapter 作为期望接口,具体的适配器实现类用于对目标类进行适配,Controller 作为需要适配的类。
Spring MVC 中的 Controller 种类众多,不同类型的 Controller 通过不同的方法来对请求进行处理。
如果不利用适配器模式的话,DispatcherServlet 直接获取对应类型的 Controller,需要的自行来判断,那将出现n个if else。

2、spring AOP中的适配器模式
在Spring的Aop中,使用的 Advice(通知) 来增强被代理类的功能。
Advice的类型有:MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice
在每个类型 Advice 都有对应的拦截器,MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor
Spring需要将每个 Advice 都封装成对应的拦截器类型,返回给容器,所以需要使用适配器模式对 Advice 进行转换。

© 著作权归作者所有

请把小熊还给我_m
粉丝 22
博文 52
码字总数 69711
作品 0
杭州
私信 提问
加载中

评论(2)

donghui2020
donghui2020
加油~~
请把小熊还给我_m
请把小熊还给我_m 博主
😆好
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
2018/11/06
219
0
极速理解设计模式系列【目录索引】

这是一个老生常谈的设计模式系列文章,本系列力图从最简洁的语言和最易理解的实例来让大家认识设计模式的思想和思路,从而在实际项目中能够用到一二。现在将本系列文章详列如下: 极速理解设...

程兴亮
2011/10/31
0
0
《JavaScript设计模式与开发实践》最全知识点汇总大全

系列文章: 《JavaScript设计模式与开发实践》基础篇(1)—— this、call 和 apply 《JavaScript设计模式与开发实践》基础篇(2)—— 闭包和高阶函数 《JavaScript设计模式与开发实践》模式...

嗨呀豆豆呢
2019/01/04
0
0
编程中的那些套路——关于策略模式

该文章属于《编程中的那些经典套路——设计模式汇总》系列,并且以下内容基于语言PHP 今天讲讲策略模式,策略模式 和工厂模式十分相像(或者说在代码逻辑层面,他们是一样的)。 但策略模式与...

gzchen
2018/08/27
0
0
javascript 设计模式之工厂(Factory)模式

工厂模式介绍 工厂模式是一个创建型的模式,主要就是创建对象。其中工厂模式又分为简单工厂模式和抽象工厂模式。简单工厂模式是通过工厂方法确定创建 对应类型的对象。抽象工厂模式是通过子类...

hlxiong
2014/04/14
386
0

没有更多内容

加载失败,请刷新页面

加载更多

如何在Linux中一步更改文件夹及其所有子文件夹和文件的权限? [关闭]

问题: I would like to change permissions of a folder and all its sub folders and files in one step (command) in Linux. 我想在Linux中一步(命令)更改文件夹及其所有子文件夹和文件......

javail
41分钟前
13
0
Gradle 6 针对已有的构建如何创建一个构建扫描

有关构建扫描的定义为: 构建扫描(build scan)是一个中心化并且可以共享的构建记录。这个构建记录通常能够告诉在构建中发生了什么并且为什么会发生。 通过应用构建扫描插件到你的项目中,你...

honeymoose
今天
17
0
C语言动态内存分配:(一)malloc/free的实现及malloc实际分配/释放的内存

一、malloc/free概述 malloc是在C语言中用于在程序运行时在堆中进行动态内存分配的库函数。free是进行内存释放的库函数。 1、函数原型 #include <stdlib.h> void *malloc( size_t size ); v...

shzwork
今天
17
0
什么是JavaBean? - What is a JavaBean exactly?

问题: I understood, I think, that a "Bean" is a Java class with properties and getters/setters. 我认为,“ Bean”是具有属性和getter / setter的Java类。 As much as I understand,......

技术盛宴
今天
27
0
深圳援鄂最后一批工作人员归来,88万元关爱金发放至85人

中国公益在线3月31日深圳讯 深圳援鄂最后一批工作人员归来......深圳市民政局、深圳市卫健委和深圳市慈善会发起了“深爱战疫天使基金”项目,联合龙华区慈善会和 永贤慈善基金会,进行第二次...

传承天下融媒体中心
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部