从SpringMVC看适配器模式

简介: 从SpringMVC看适配器模式

引言


最近在读springMVC源码的时候,发现在springMVC的整个流程架构当中,适配器模式是一个非常经典的应用,当然适配模式是一个比较简单的设计模式。


一、springMVC为什么使用适配器模式?


我们知道在springmvc的架构中,控制器(controller)的实现方式有多种,例如直接使用@Controller注解、直接实现 controller接口等, 每一种实现方式都对应不同的处理逻辑,所以如果我们直接调用controller的话,我们的代码就是这个鬼样子,一堆的if else....:

if(mappedHandler.getHandler() instanceof MultiActionController){  
   ((MultiActionController)mappedHandler.getHandler()).xxx  
}else if(mappedHandler.getHandler() instanceof XXX){  
    ...  
}else if(...){  
   ...  
}

如果我们是这样写代码的话, 现在如果又增加了一种controller的实现方式的话,我们就需要在上面方法中增加一个if else,这种形式就使得代码非常不好维护,并且也违反了设计模式中的开闭原则。


因此SpringMVC中 定义了一个适配器接口,使得每一种controller都对应一个 适配器类,让适配器代替controller执行对应的方法,这样我们在扩展controller的时候,只需要增加一个对应的适配器类就可以了。


下面我们看一下, 适配器模式的实现框架:


二、基本概念


适配器模式就是把一个类的接口替换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。


三、适用场景


用电器做例子,笔记本电脑的插头一般都是三相的,即除了阳极、阴极外,还有一个地极。而有些地方的电源插座却只有两极,没有地极。电源插座与笔记本电脑的电源插头不匹配使得笔记本电脑无法使用。这时候一个三相到两相的转换器(适配器)就能解决此问题,而这正像是本模式所做的事情。


四、核心组件


1)目标接口(Target):客户端所期待的接口,目标可以使具体的或抽象类, 也可以是接口

2)需要适配的类(Adaptee):需要适配的类或者适配者类

3)适配器(Adapter):通过包装一个需要适配的对象,把原有接口转换成目标接口


五、两种适配器模式


1、类适配器模式(采用继承方式实现)



20160909103837529.png


目标接口代码:

public interface Target {
    /**
     * @Description: 标准接口
     * @author: zhenghao
     * @date: 2020/11/23 20:07
    */
    void request();
}

普通功能类:

public class ConcreteTarget implements  Target {
    @Override
    public void request() {
        System.out.println("实现普通功能。。。");
    }
}

实现特殊功能的类:


1. public void specificRequest(){
2.         System.out.println("实现特殊功能。。。");
3.     }


适配器类,通过继承实现:

public class Adapter extends Adaptee implements  Target {
    @Override
    public void request() {
        //执行父类的方法
        super.specificRequest();
    }
}

测试类:

public class Client {
    public static void main(String[] args) {
        //实现普通功能
        Target target = new ConcreteTarget();
        target.request();
        //实现特殊功能
        Target adapter = new Adapter();
        adapter.request();
    }
}

2) 对象的适配器模式(通过组合方式实现)


20160909104006447.png

在上述类的适配器的基础上,修改适器类,直接实现标准接口,代码如下:

public class AdapterTwo implements Target {
    private Adaptee adaptee = new Adaptee();
    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

测试类:


public class Client {
    public static void main(String[] args) {
        //实现普通功能
        Target target = new ConcreteTarget();
        target.request();
        //实现特殊功能
        Target adapter = new AdapterTwo();
        adapter.request();
    }
}


六、小结


6.1 优点


6.1.1 通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。


   6.1.2 复用了现存的类,解决了现存类和复用环境要求不一致的问题。


   6.1.3 将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。


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


 6.2 缺点


   对于对象适配器来说,更换适配器的实现过程比较复杂。


 6.3 适用场景


   6.3.1 系统需要使用现有的类,而这些类的接口不符合系统的接口。


   6.3.2 想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。


   6.3.3 两个类所做的事情相同或相似,但是具有不同接口的时候。


   6.3.4 旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。


   6.3.5 使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。


我们彻底了解了适配模式,在入手看springmvc的源码会轻松很多,在下一篇博客,我们将动手,手写一个简易版的springmvc框架!

目录
相关文章
|
Java Unix 程序员
【OS Ctags】Vim 代码阅读工具 Ctags
【OS Ctags】Vim 代码阅读工具 Ctags
306 0
【OS Ctags】Vim 代码阅读工具 Ctags
|
消息中间件 运维 负载均衡
【Kafka】Kafka 实现负载均衡与故障转移
【4月更文挑战第5天】【Kafka】Kafka 实现负载均衡与故障转移
|
存储 Kubernetes 调度
【K8S系列】第二讲:Pod入门
【K8S系列】第二讲:Pod入门
245 0
|
JSON NoSQL MongoDB
MongoDB Schema设计实战指南:优化数据结构,提升查询性能与数据一致性
【8月更文挑战第24天】MongoDB是一款领先的NoSQL数据库,其灵活的文档模型突破了传统关系型数据库的限制。它允许自定义数据结构,适应多样化的数据需求。设计MongoDB的Schema时需考虑数据访问模式、一致性需求及性能因素。设计原则强调简洁性、查询优化与合理使用索引。例如,在构建博客系统时,可以通过精心设计文章和用户的集合结构来提高查询效率并确保数据一致性。正确设计能够充分发挥MongoDB的优势,实现高效的数据管理。
326 3
|
测试技术 API
接口设计原则与最佳实践指南
接口设计原则与最佳实践指南
|
监控 关系型数据库 MySQL
MySQL 查询数据库响应时长详解
- 启用慢查询日志(`slow_query_log`)分析超时查询,调整`long_query_time`阈值。 - 使用`EXPLAIN`检查查询执行计划,优化索引和查询结构。 - `SHOW PROFILE`揭示查询各阶段耗时,辅助性能调优。 - 开启Performance Schema监控服务器,通过`events_statements_summary_by_digest`等表分析性能。 - MySQL Workbench和Percona Toolkit等工具提供额外的性能分析和管理功能。 - 优化技巧:创建合适索引,精简查询,调整数据库配置以提升响应速度。
|
JavaScript 前端开发
【JS】获取当前时间,且格式为yyyy-MM-dd hh:mm:ss
【JS】获取当前时间,且格式为yyyy-MM-dd hh:mm:ss
399 0
|
机器学习/深度学习 PyTorch 算法框架/工具
|
API 开发工具 开发者
全面的开发者文档和用户目标解析:API 文档指南和开发者旅程
开发者文档,也称为 API 文档,是一种专门针对软件开发人员的技术写作形式。这种类型的文档通常包括 API 的技术规范、代码注释、软件设计和架构以及软件开发中涉及的其他详细技术描述。开发者文档是开发人员的重要工具,因为它提供了使用和集成特定软件、库或 API 的必要指南、标准和示例。开发者文档的结构和内容的全面性会根据它所描述的软件的复杂性而大不相同,但主要目的是帮助开发人员理解、使用和高效地为软件做出贡献。
813 2
|
Go
Go语言type关键字终于被玩明白了 类型别名的秘密都在这里
Go语言type关键字终于被玩明白了 类型别名的秘密都在这里
436 0