Spring中常见的设计模式——适配器模式
一、适配器模式的应用场景
适配器模式(Adapter Pattern)是指将一个类的接口转换成用户期待的另一个接口,使原本接口不兼容的类可以一起工作,属于构造设计模式。
适配器适用于以下几种业务场景:
- 已经存在的类的方法和需求不匹配(方法结果相同或相似)的情况。
- 适配器模式不是软件初始阶段应该考虑的设计模式,是随着软件的开发,由于不同产品、不同厂家造成功能类似而接口不同的问题的解决方案,有点亡羊补牢的感觉。
二、重构第三方登录自由适配的业务场景
将原来的单一支持用户名和密码登录,扩展为可以支持微信和手机登录。
创建统一返回结果ResultMsg:
- @Data
public class ResultMsg {
private Integer code;
private String msg;
private Object data;- public ResultMsg(Integer code, String msg, Object data) {
this.code = code;
this.data = data;
this.msg = msg;
}
}
老系统登录代码如下:
- public class SignInService {
- public ResultMsg regist(String userName, String passWord) {
- return new ResultMsg(200, "注册成功", new Member());
- }
- public ResultMsg login(String userName, String passWord) {
- return null;
- }
- }
为了遵循开闭原则,我们不修改老系统代码,下面是Member类:
- @Data
- public class Member {
- private String userName;
- private String passWord;
- private String mid;
- private String info;
- }
我们优雅的根据不同登录方式创建不同的“Adapter”,首先创建LoginAdapter:
- public interface LoginAdapter {
- boolean support(Object adapter);
- ResultMsg login(String id, Object adapter);
- }
手机登录:
- public class LoginForTelAdapter implements LoginAdapter {
- @Override
- public boolean support(Object adapter) {
- return adapter instanceof LoginForTelAdapter;
- }
- @Override
- public ResultMsg login(String id, Object adapter) {
- return null;
- }
- }
微信登录:
- public class LoginForWechatAdapter implements LoginAdapter {
- @Override
- public boolean support(Object adapter) {
- return adapter instanceof LoginForWechatAdapter;
- }
- @Override
- public ResultMsg login(String id, Object adapter) {
- return null;
- }
- }
接着,创建第三方登录兼容接口IPassportForThid:
- public interface IPassportForThird {
- ResultMsg loginForTel(String telephone, String code);
- ResultMsg loginForWechat(String id);
- ResultMsg loginForResist(String userName, String passWord);
- }
实现兼容PassportForThirdAdapter:
- public class PassportForThirdAdapter extends SignInService implements IPassportForThird {
- @Override
- public ResultMsg loginForTel(String telephone, String code) {
- return null;
- }
- @Override
- public ResultMsg loginForWechat(String id) {
- return null;
- }
- @Override
- public ResultMsg loginForResist(String userName, String passWord) {
- super.regist(userName, passWord);
- return super.login(userName, passWord);
- }
- //这里使用简单工厂及策略模式
- private ResultMsg procssLogin(String key, Class<? extends LoginAdapter> clazz) {
- try {
- LoginAdapter adapter = clazz.newInstance();
- if (adapter.support(adapter)) {
- return adapter.login(key, adapter);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- }
前面每个适配器都加上了support()方法,用来判断箭筒。support()方法的参数也是Object类型,而support()来自接口。适配器并不依赖接口,我们使用接口只是为了代码规范。
三、适配器模式在源码中的体现
Spring中的AOP中AdvisorAdapter类,它有三个实现:MethodBeforAdviceAdapter、AfterReturnningAdviceAdapter、ThrowsAdviceAdapter。
先看顶层接口AdviceAdapter的源代码:
- public interface AdvisorAdapter {
- boolean supportsAdvice(Advice var1);
- MethodInterceptor getInterceptor(Advisor var1);
- }
再看MethodBeforAdviceAdapter:
- public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
- private final MethodBeforeAdvice advice;
- public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
- Assert.notNull(advice, "Advice must not be null");
- this.advice = advice;
- }
- public Object invoke(MethodInvocation mi) throws Throwable {
- this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
- return mi.proceed();
- }
- }
其他两个类就不看了。Spring会根据不同的AOP配置来使用对应的“Advice”,与策略模式不同的是,一个方法可以同时拥有多个“Advice”。
四、适配器模式的优缺点
优点:
- 能提高类的透明性和复用性,现有的类会被复用但不需要改变。
- 目标类和适配器类解耦,可以提高程序的扩展性。
- 在很多业务场景中符合开闭原则。
缺点:
- 在适配器代码编写过程中需要进行全面考虑,可能会增加系统复杂度。
- 增加代码阅读难度,过多使用适配器会使系统代码变得凌乱。
Spring中常见的设计模式——适配器模式的更多相关文章
- Spring中常见的设计模式——代理模式
一.代理模式的应用场景 生活中的中介,黄牛,等一系列帮助甲方做事的行为,都是代理模式的体现.代理模式(Proxy Pattern)是指为题对象提供一种代理,以控制对这个对象的访问.代理对象在客户端和目 ...
- Spring中常见的设计模式——单例模式
一.单例模式的应用场景 单例模式(singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.J2EE中的ServletContext,ServletCon ...
- Spring中常见的设计模式——委派模式
一.委派模式的定义及应用场景 委派模式(Delegate Pattern)的基本作用是负责任务的调用和分配,跟代理模式很像,可以看做特殊情况下的静态的全权代理,但是代理模式注重过程,而委派模式注重结果 ...
- Spring中常见的设计模式——策略模式
策略模式(Strategy Pattern) 一.策略模式的应用场景 策略模式的应用场景如下: 系统中有很多类,而他们的区别仅仅在于行为不同. 一个系统需要动态的在集中算法中选择一种 二.用策略模式实 ...
- Spring中常见的设计模式——工厂模式
一.简单工厂模式 简单工厂模式(Simple Factory Pattern)由一个工厂对象决定创建哪一种产品类的实例,简单工厂模式适用于工厂类负责创建对象较少的情况,且客户端只需要传入工厂类的参数, ...
- Spring中常见的设计模式——原型模式
1.原型模式应用场景 当遇到大量耗费劳动力的 get,set赋值场景时,如下: public class SetGetParam { public void setParam(UserDto user ...
- Spring中常见的设计模式——模板模式
一.模板模式的应用场景 模板模式又叫模板方法模式(Template Method Pattern),指定义一个算法的骨架,并允许自雷为一个或者多个步骤提供实现.模板模式使得子类可以在不改变算法结果的情 ...
- 设计模式:JDK和Spring中常见的设计模式
设计模式 总结 类 工厂模式 封装创建过程,只对结果负责 BeanFactory.Calender 单例模式 全局唯一 ApplicationContext.Calender 原型模式 多重影分身之术 ...
- spring 中常用的设计模式
一. Spring 中常见的设计模式 工厂模式 : BeanFactory 装饰器模式: BeanWrapper 代理模式: AopProxy 单例模式: ApplicationContext 委派模 ...
随机推荐
- H3C PPP MP配置示例一
- 微软的可疑更新DhMachineSvc.exe
最近微软大范围的推出了一个只针对中国的更新,包含了DhMachineSvc.exe,也就是所谓的'微软设备健康助手服务'. 这个更新很神秘,首先这个更新只针对中国区,其次这个更新支持WinXP,第三这 ...
- codeforce 382 div2 E —— 树状dp
题意:给一棵n个结点的无根树染色,求使每个结点距离为k的范围内至少有一个被染色的结点的总染色方法数目 分析:首先我们定义: 对于结点v, 如果存在一个黑色结点u距离v不超过k,则结点v被“控制” 首先 ...
- http请求头包括了哪些常见内容
Host: www.study.com // 请求的地址域名和端口,不包括协议 Connection: keep-alive // 连接类型,持续连接 Upgrad ...
- tf.train.match_filenames_once()
文件匹配之用 官方解释: 调用样例: https://bbs.csdn.net/topics/392271556 返回值样例:
- H3C 计算子网内可用主机地址数
- Priest John's Busiest Day (2-sat)
题面 John is the only priest in his town. September 1st is the John's busiest day in a year because th ...
- 【34.54%】【codeforces 675E】Trains and Statistic
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- supported platform
Target name Platform Architecture Endianness Developer(s) Known Issues/Notes adm5120 Infineon/ADMtek ...
- docker(整理中
docker镜像默认的下载地址就是docker的官网,而他们的官网在国内没有节点,时不时就被国家防火墙隔绝,会出现DNS解析不到,或者找不到镜像等狗血提示. 解决的方法有三个: 第一,就是不断尝试,因 ...