适配器模式

定义: 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

通俗一些就是两个不同、没有关联的接口,如果通过一个适配器或者拦截器,可以进行一起协作。

优点:

  1. 可以让任何两个没有关联的类一起运行。
  2. 提高了类的复用。
  3. 灵活性好。

缺点: 过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接 口的实现,一个系统如果太多出现这种情况,无异于一场灾难。

Spring Aop适配器+代理模式案例

Spring架构中涉及了很多设计模式,本文来介绍下Spring中在AOP实现时Adapter模式的使用。AOP本质上是Java动态代理模式的实现和适配器模式的使用。

我们基于Spring的前置通知来实现一个打卡案例,再基于前置通知讲解前置适配模式。

创建打卡接口: PunchCard 定义打卡方法,代码如下:

public interface PunchCard { //打卡记录 void info(String name);
}

定义打卡实现: PunchCardImpl 实现打卡操作,代码如下:

public class PunchCardImpl implements PunchCard { @Override public void info(String name) { System.out.println(name+" 打卡成功!"); }
}

前置通知创建: PunchCardBefore 实现在打卡之前识别用户身份,代码如下:

public class PunchCardBefore implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable {        System.out.println("身份识别通过!"); }
}

spring.xml配置前置通知:

<!--打卡-->
<bean id="punchCard" class="com.itheima.adapter.PunchCardImpl"></bean>
<!--前置通知-->
<bean id="punchCardBefore" class="com.itheima.adapter.PunchCardBefore"></bean>
<!--代理配置-->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 指定目标对象    --> <property name="target" ref="punchCard"/> <!-- 指定目标类实现的所有接口    --> <property name="interfaces" value="com.itheima.adapter.PunchCard"/> <!-- 指定切面    --> <property name="interceptorNames" > <list> <value>punchCardBefore</value> </list> </property>
</bean>

测试效果如下:

正在初始化打卡程序!
王五 打卡成功!

Spring AOP适配器体系


前置通知其实就是适配器模式之一,刚才我们编写的前置通知实现了接口 MethodBeforeAdvice。Spring容器将每 个具体的advice封装成对应的拦截器,返回给容器,这里对advice转换就需要用到适配器模式。我们来分析下适配器 的实现:
如下代码实现了接口 BeforeAdvice,而 BeforeAdvice继承了 Advice接口,在适配器接口 AdvisorAdapter里面 定义了方法拦截。

public interface MethodBeforeAdvice extends BeforeAdvice { void before(Method method, Object[] args, @Nullable Object target) throws Throwable;
}

AdvisorAdapter:定义了2个方法,分别是判断通知类型是否匹配,如果匹配就会获取对应的方法拦截。

public interface AdvisorAdapter { // 判断通知类型是否匹配 boolean supportsAdvice(Advice advice); // 获取对应的拦截器 MethodInterceptor getInterceptor(Advisor advisor);
}

MethodBeforeAdviceAdapter:实现了 AdvisorAdapter,代码如下:

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable { @Override public boolean supportsAdvice(Advice advice) { return (advice instanceof MethodBeforeAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); // 通知类型匹配对应的拦截器 return new MethodBeforeAdviceInterceptor(advice); }
}

刚才我们在spring.xml中配置了代理类,代理类通过DefaultAdvisorAdapterRegistry类来注册相应的适配器,我们可以在

深入浅出设计模式---4、适配器模式相关推荐

  1. C#设计模式(7)——适配器模式(Adapter Pattern)

    一.引言 在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象.那么如果将"将现存的对象" ...

  2. 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)

    [索引页] [源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabcd 介绍 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本 ...

  3. 跟JBPM学设计模式之适配器模式

    跟JBPM学设计模式之适配器模式 模式简介 适配器模式(Adapter),将一个类的接口转换成客户希望的另一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 说起适配器模式 ...

  4. python适配器模式角色_Python设计模式之适配器模式原理与用法详解

    本文实例讲述了Python设计模式之适配器模式原理与用法.分享给大家供大家参考,具体如下: 适配器模式(Adapter Pattern):将一个类的接口转换成为客户希望的另外一个接口. 下面是一个适配 ...

  5. 【设计模式】—— 适配器模式Adapter

    模式意图 如果已经有了一种类,而需要调用的接口却并不能通过这个类实现.因此,把这个现有的类,经过适配,转换成支持接口的类. 换句话说,就是把一种现有的接口编程另一种可用的接口. 模式结构 [类的适配器 ...

  6. 设计模式适配器模式_21世纪的设计模式:适配器模式

    设计模式适配器模式 这是我的演讲的第三部分," 21世纪的设计模式" . 适配器模式桥接世界. 在一个世界中,我们有一个概念的界面. 在另一个世界,我们有不同的界面. 这两个接口有 ...

  7. Java面试题:单例设计模式、适配器模式的不同方式

    QUESTION:单例设计模式.适配器模式的不同方式? ANSWER: 1.单例设计模式,适配器设计模式     单利设计模式:             在java中,单例模式是指为了保证类在内存中只 ...

  8. [学习笔记]设计模式[6]-{适配器模式外观模式}

    设计原则 最少知识原则:只和你的密友谈话 这个原则的意思是,在系统设计的过程中,不要让太多的类耦合在一起,免得对系统一部分的修改会影响到其他部分.在设计系统之前,应该首先注意对象与对象之间的交互关系, ...

  9. 适配器模式_21世纪的设计模式:适配器模式

    适配器模式 这是我的演讲的第三部分," 21世纪的设计模式" . 适配器模式桥接世界. 在一个世界中,我们有一个概念的界面: 在另一个世界中,我们有不同的界面. 这两个接口有不同的 ...

  10. 设计模式回顾——适配器模式(C++)

    文章目录 1 前言 2 什么是适配器模式 2.1 生活中的适配器 2.2 适配器模式含义 2.3 适配器模式作用 3 适配器模式优缺点 3.1 适配器优缺点 3.2 类适配器优缺点 3.3 对象适配器 ...

最新文章

  1. 2021贝叶斯数据分析-原作者开课啦!
  2. 日语python_边学日语边学python语法
  3. Git之如何解决sourceTree已经pull全部下来但是本地没有更新的问题
  4. python缓冲区_如何在Python中使用Google的协议缓冲区
  5. [Leedcode][JAVA][第739题][每日温度][暴力][单调栈]
  6. 信息学奥赛一本通(1200:分解因数)
  7. Assemby 打包并启动jar包
  8. 非常详细GC学习笔记
  9. Linux常用命令笔记2---文件管理2
  10. 一文看懂搜狗招股书:90次提到AI,王小川持股5%,净利3.7亿
  11. 讲解开源项目:一步步跑起来个 Java 前后端分离的人力资源管理系统
  12. Python基础语法测验习题(有答案版)
  13. 数仓知识05:事实表和维度表的概念
  14. 为什么快捷指令无法将媒体转换为文本_刘星文:快捷指令这个神器,让你的 iPhone 好用到飞起...
  15. 滤芯怎么换 石头机器人_拆开看个究竟,石头扫拖一体机器人T6到底如何?
  16. 求圆周长,圆面积,圆球表面积、圆球体积,圆柱体积
  17. 支付宝支付-java-sdk
  18. 推荐一个数据可视化大屏幕报表开源系统
  19. 动手下载网易课程视频 -- 正式下载
  20. matlab中怎么输入特殊符号

热门文章

  1. c语言编译器苹果下载,c语言编译器ios下载
  2. WINDOWS 98 启动盘(加强版)
  3. csdn 积分/c币获取方法
  4. 安装qt qmake 错误:could not find a Qt installation of ''
  5. 使用RoboCopy 命令
  6. 一 c语言程序设计 张玉生版
  7. finereport 格式化金额函数_帆软报表常用函数总结
  8. python制作无限弹窗_Python无限弹窗,开机启动,打包为exe程序
  9. 电视盒子 android tv6,【亲测】S905L/S905L-B安卓TV6.0通刷固件
  10. java人脸识别怎么写-------源码附上