12.从项目经理的生存哲学到适配器模式(Adapter Pattern)

如果这个世界没有了项目经理,事情的发展可能并不会如同想象中一样美好,相反,对于开发人员来说可能是噩梦的开始。
比如:
客户因为几个需求的具体实现大发雷霆,甚至开始恶语相向,一通含ma量极高的“斯伯坦语”下来,瞬间让性情耿直的开发人员集体开团,场面一度难以控制。因为对于大多数技术部门的人员来说,这种过度“世俗”的沟通方式并不能被接受。
但如果此时有一个经验丰富的项目经理作为缓冲夹在中间,将客户的“斯伯坦语”过滤处理成纯粹的需求,传达给技术人员,再将技术人员的解决方案加以“怀柔的”修饰传递给客户。世界是不是就变得美好了呢?
语言是门艺术,沟通充满了技巧。


一言

适配器模式即:将某个类的接口转换成客户端期望的另一个接口表示,让原本不匹配的两个对象可以协同工作。


概述

在刚刚的例子中,项目经理实际上就是充当了适配器的角色,让原本水火不容的客户和技术人员能够携起手来,共同完成项目。其核心在于适配器的兼容性。
在软件设计领域,通常将适配器模式划分为结构型模式的一种。从用户的角度来看,是看不到被适配者的,就比如客户通常不会关心技术人员的存在,从这个角度来说,整体的结构的耦合度是很低的。用户调用适配器,适配器再调用被适配者。
在适配器的具体实现上,通常有:类适配器、对象适配器、接口适配器三种。


类适配器

项目经理: 客户就是我的爸爸!

在这里插入图片描述

参照我们此前描述的情景,项目经理(适配器类)需要将客户类(被适配对象)当作父亲,通过继承获得客户的初始需求,同时还要掌握一定管理能力(实现管理接口),通过管理能力将客户的需求进行处理,交付给开发人员。

图解

在这里插入图片描述

实例

我们假定客户的每一个需求都带有一个愤怒值,当这个愤怒值高于10时,开发人员将认位自己受到了冒犯并拒绝工作,而项目经理则需要即时的将客户的需求通过处理交付给开发人员,以期工作的正常开展。
客户

public class Customer {
    public int communicate(){
        int anger = 10000;
        System.out.println("沟通需求,愤怒指数:"+anger);
        return anger;
    }
}

管理能力

public interface Manage {
    public int skill();
}

项目经理

public class ProjectManager extends Customer implements Manage{
    @Override
    public int skill() {
        int anger = communicate();
        return anger/1000;
    }
}

开发人员

public class Devops {
    public void work(Manage manage){
        if (manage.skill()>10)
            System.out.println("你的态度让我无法工作");
        else
            System.out.println("沟通方式很尊重我,工作包在我身上");
    }
}

分析

Java是单继承机制,所以类适配器需要继承客户类这一点算是一个缺点,因为这要求管理能力必须是接口,有一定局限性;
客户类的方法在Adapter(项目经理)中都会暴露出来,也增加了使用的成本。由于其继承了客户类,所以它可以根据需求重写客户类的方法,使得Adapter的灵活性增强了。


对象适配器

项目经理:客户不是我的爸爸,他是我的家人。我们彼此尊重、方向一致。

在这里插入图片描述

实际上我们已经清楚的看到了类适配器存在的问题:项目经理的膝盖太软了,一直把客户(被适配对象)当作自己的父亲,这使得整个结构存在着很大的局限性。
对象适配的思路上就是让项目经理站起来,不是直接继承客户,而是通过持有客户的对象来解决兼容问题。

图解

在这里插入图片描述

实例核心

public class ProjectManager implements Manage {
    private Customer customer;

    public ProjectManager(Customer customer){
        this.customer = customer;
    }

    @Override
    public int skill() {
        int anger = customer.communicate();
        return anger/1000;
    }
}

分析

对象适配器和类适配器其实算是同一种思想,只不过实现方式不同根据合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承被适配对象的局限性问题,也不再要求适配能力必须是接口。
使用成本更低,结构上也更灵活。


接口适配器

有很多资料也将这种方式称为“缺省适配器模式”,顾名思义,当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现 (空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
这其实非常适用于一个接口不想使用其所有方法的情况。
在这里插入图片描述
这种方式很容易理解,这里不过多赘述。


适配器模式在SpringMVC源码的应用

相信有的朋友看到SpringMVC再结合我们上文讲到的适配器模式(Adapter)就已经恍然大悟了。SpringMVC框架中一个非常重要的角色就是HandlerAdapter。
我们可以回想一下SpringMVC的工作过程(这里不做展开,忘记了的同学可以查阅下相关资料),其中有一个重要环节就是DispatchServlet 会根据 收到的Handler 选择一个合适的HandlerAdapter。这里就是适配器模式的关键应用。
下面我将相关源码主体剥离了一部分出来,大家可以体会下。

部分源码

Controller

public interface Controller {
}
class HttpController implements Controller {
    public void doHttpHandler() {
        System.out.println("http...");
    }
}

class SimpleController implements Controller {
    public void doSimplerHandler() {
        System.out.println("simple...");
    }
}

class AnnotationController implements Controller {
    public void doAnnotationHandler() {
        System.out.println("annotation...");
    }
}

HandlerAdapter

public interface HandlerAdapter {
    public boolean supports(Object handler);
    public void handle(Object handler);
}

class SimpleHandlerAdapter implements HandlerAdapter {
    public void handle(Object handler) {
        ((SimpleController) handler).doSimplerHandler();
    }

    public boolean supports(Object handler) {
        return (handler instanceof SimpleController);
    }
}

class HttpHandlerAdapter implements HandlerAdapter {
    public void handle(Object handler) {
        ((HttpController) handler).doHttpHandler();
    }

    public boolean supports(Object handler) {
        return (handler instanceof HttpController);
    }
}

class AnnotationHandlerAdapter implements HandlerAdapter {
    public void handle(Object handler) {
        ((AnnotationController) handler).doAnnotationHandler();
    }

    public boolean supports(Object handler) {
        return (handler instanceof AnnotationController);
    }
}

DispatchServlet

public class DispatchServlet {
    public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();

    public DispatchServlet() {
        handlerAdapters.add(new AnnotationHandlerAdapter());
        handlerAdapters.add(new HttpHandlerAdapter());
        handlerAdapters.add(new SimpleHandlerAdapter());
    }

    public void doDispatch() {
        HttpController controller = new HttpController();
        // AnnotationController controller = new AnnotationController();
        //SimpleController controller = new SimpleController();
        HandlerAdapter adapter = getHandler(controller);
        adapter.handle(controller);
    }

    public HandlerAdapter getHandler(Controller controller) {
        for (HandlerAdapter adapter : this.handlerAdapters) {
            if (adapter.supports(controller)) {
                return adapter;
            }
        }
        return null;
    }

    public static void main(String[] args) {
        new DispatchServlet().doDispatch(); // http...
    }
}

图解

在这里插入图片描述

分析

对于多种Controller,应该有对应的适配器对其做处理。
在DispatchServlet从request中取到handler对象后,适配器可以得到自己希望的Controller进而通过getHandler方法得到对应的适配器,在通过适配器执行handle,也就能执行对应controller的对应方法了。


好啦,希望通过此文能让大家对适配器模式有更深一步的认识,也期待获得大家的指正或共鸣。
关注我,共同进步,每周至少一更。——Wayne

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/357304.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多种协议转IEC104网关BE115

随着电力系统信息化建设和数字化转型的进程不断加速&#xff0c;对电力能源的智能化需求也日趋增强。健全稳定的智慧电力系统能够为工业生产、基础设施建设以及国防建设提供稳定的能源支持。在此背景下&#xff0c;高性能的工业电力数据传输解决方案——协议转换网关应运而生&a…

centos7上安装mysql5.7并自定义数据目录路径

1、卸载mariadb rpm -qa |grep mariadb #查出来的结果是mariadb-libs-5.5.68-1.el7.x86_64 rpm -e mariadb-libs-5.5.68-1.el7.x86_64 --nodeps #卸载查到的结果 2、官网下载响应的tar.gz包&#xff0c;比如mysql-5.7.38-el7-x86_64.tar.gz &…

回归预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络多变量回归预测

回归预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络多变量回归预测 目录 回归预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-LSTM【24年新算…

js实现填涂画板

文章目录 1实现效果2 实现代码 凑个数&#xff0c;存粹是好玩儿&#xff0c;哈哈... 1实现效果 最上方一栏&#xff1a; 左侧是颜色按钮&#xff0c;点击选中颜色&#xff0c; 中间是功能按钮&#xff0c;重置颜色、清空画板、回退、涂改液&#xff08;填涂色置为白色&#xff…

数字人的不足

在数字化环境中对于事物或情况的感知能力存在缺陷。这可能涉及到人类对数字化信息的理解、利用和应对能力方面的问题&#xff0c;也可能涉及到数字化系统或技术本身的局限性。在当今数字化时代&#xff0c;人们对数字化信息的感知和理解至关重要&#xff0c;因为数字化技术已经…

2023年算法CDO-CNN-BiLSTM-ATTENTION回归预测(matlab)

2023年算法CDO-CNN-BiLSTM-ATTENTION回归预测&#xff08;matlab&#xff09; CDO-CNN-BiLSTM-Attention切诺贝利灾难优化器优化卷积-长短期记忆神经网络结合注意力机制的数据回归预测 Matlab语言。 切诺贝利灾难优化器Chernobyl Disaster Optimizer (CDO)是H. Shehadeh于202…

4D毫米波雷达——ADCNet 原始雷达数据 目标检测与可行驶区域分割

前言 本文介绍使用4D毫米波雷达&#xff0c;基于原始雷达数据&#xff0c;实现目标检测与可行驶区域分割&#xff0c;它是来自2023-12的论文。 会讲解论文整体思路、输入分析、模型框架、设计理念、损失函数等&#xff0c;还有结合代码进行分析。 论文地址&#xff1a;ADCNe…

为什么说语言的主要作用不是交流而是思考

一般人常常以为&#xff0c;语言最重要的作用是帮助人们表达思想和情感。但最近偶然看到对乔姆斯基的一个采访&#xff0c;他认为&#xff1a;语言的主要作用不是交流&#xff0c;而是思考的工具&#xff0c;即语言是帮助人们组织和理解思维的过程。以下是几点说明为什么说语言…

Vue-43、Vue中组件自定义事件

1、给学生绑定atguigu事件 2、在组件内触发事件 第二种写法 传多个参数。 解绑 解绑一个事件 解绑多个自定义事件 this.$off([xxx1,xxx2]);解绑所有事件 this.$off();总结

宝塔控制面板配置SSL证书实现网站HTTPS

宝塔安装SSL证书提前申请好SSL证书&#xff0c;如果还没有&#xff0c;先去Gworg里面申请&#xff0c;一般几分钟就可以下来&#xff0c;申请地址&#xff1a;首页-Gworg官方店-淘宝网 一、登录邮箱下载&#xff1a;Gworg证书文件目录 &#xff0c;都会有以下五个文件夹。宝塔…

【算法】怪盗基德的滑翔翼(最大上升子序列)

题目 怪盗基德是一个充满传奇色彩的怪盗&#xff0c;专门以珠宝为目标的超级盗窃犯。 而他最为突出的地方&#xff0c;就是他每次都能逃脱中村警部的重重围堵&#xff0c;而这也很大程度上是多亏了他随身携带的便于操作的滑翔翼。 有一天&#xff0c;怪盗基德像往常一样偷走…

一进一出模拟量信号隔离变送器

一进一出模拟量信号隔离变送器 捷晟达科技推出一进一出模拟量信号隔离变送器 深圳捷晟达科技推出一款具有隔离,放大,转换保护功能的一进一出的小型隔离变送器设备,该设备可以把模拟量(4-20mA/0-10V等)标准信号转换用户需要的信号,该产品具有抗EMC干扰,可以有效的保护后级设备安…

第一节课,用户管理--后端初始化,项目调通。二次翻工2

一、网址来源&#xff1a; 快速开始 | MyBatis-Plus (baomidou.com) 进程&#xff1a; ​ 二、[此处不看]添加测试类&#xff0c;看下效果 2.1 参考 一、第一节课&#xff0c;用户管理--后端初始化&#xff0c;项目调通-CSDN博客 ​ 2.2 新建 SampleTest ​ 2.3 复…

Android Studio 下载安装配置使用入门【2024年最新】

前言&#xff1a; Android Studio 是谷歌官方提供的主要集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为 Android 平台应用开发而设计。它基于 JetBrains 的 IntelliJ IDEA 软件&#xff0c;并在此基础上增加了大量针对 Android 开发的定制功能。Android Studio 通过…

【AI视野·今日Robot 机器人论文速览 第七十六期】Fri, 12 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Fri, 12 Jan 2024 Totally 12 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Topology-Driven Parallel Trajectory Optimization in Dynamic Environments Authors Oscar de Groot, Laura Ferranti, Dari…

Java 对部分接口返回数据进行加密,或其他处理

业务场景&#xff1a;后端项目中分为PC端和移动端接口&#xff0c;移动端为例如 mobile 开头的URl&#xff0c;需求为调用移动端接口时&#xff0c;对返回数据进行加密&#xff0c;PC端不加密 import cn.hutool.core.date.DatePattern; import cn.hutool.json.JSONConfig; impo…

【C/C++ 02】希尔排序

希尔排序虽然是直接插入排序的升级版本&#xff0c;和插入排序有着相同的特性&#xff0c;即原始数组有序度越高则算法的时间复杂度越低&#xff08;预排序机制&#xff09;&#xff0c;但是是不稳定排序算法。 为了降低算法的时间复杂度&#xff0c;所以我们需要在排序之前尽…

力扣hot100 子集 回溯 超简洁

Problem: 78. 子集 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 参考题解 复杂度 时间复杂度: 添加时间复杂度, 示例&#xff1a; O ( n ) O(n) O(n) 空间复杂度: 添加空间复杂度, 示例&#xff1a; O ( n ) O(n) O(n) Code class Solution {List<Li…

HCIA---OSPF实验

题目&#xff1a; 一:IP规划及配置 IP规划没有要求&#xff0c;所以我们可以去任意规划&#xff0c;只要每个网段不要重复就好 规划的IP 配置IP 先在每个ABR设备上配置环回和接口IP&#xff0c;然后每台设备上使用display ip interface brief都查看一下 R1&#xff1a; R3&…

《2023直播电商数字化引领者》&《2023最受欢迎直播电商消费品牌TOP100》榜单发布

“ 独行快&#xff0c;众行远” 文 | 云舒&凯丰 编辑 | 小白 出品&#xff5c;极新&#xff06;北京电子商务协会 2024年1月27日&#xff0c;由极新、北京电子商务协会主办的「2024未来直播电商科技峰会」在北京首钢园三高炉A馆报告厅盛大召开。本届峰会以“预见”为主…