当前位置: 首页 > news >正文

结合案例深入解析适配器模式(二)

一、基本介绍

之所以要写适配器模式(二),是因为想强化一下练习。

而且在SpringMVC中有很多处理器适配器。

里面的源码包括一些特定的代码结构,例如isSupport()方法。

也就是说适配器还可以这么来用: 使得原本由于接口不兼容而不能一起工作、不能统一管理的那些类可以在一起工作、可以进行统一管理

二、案例

需求: 厨师的工作是 cook(),程序员的工作是 program(),司机的工作是 drive(),教师的工作是 teach(),不同的工种,其具体工作内容不同。现在程序要将这些很多个 不同工种的工作内容全部输出。

两种解决方案,其中使用适配器的又可以分为两种。

  • 解决方案一: 逐个访问每个工种对象的相应工作方法。无法循环遍历,无法统一管理。
  • 解决方案二: 使用适配器模式,将这些不兼容的具体工作转换成一个统一的工作。实现循环遍历。

为了代码简单,这里只写两个工种。cookerprogramer

1、不使用适配器模式

若不使用适配器模式,则调用者需要定义出所有的工种对象, 然后逐个工种对象的工作方法进行调用。有 30 个工种,就应调用 30 个工作方法。很麻烦。

结构如下:

1.png

先看两个工种和实现类代码:

public interface ICooker {
    String cook();
}

/**
 * ICooker的实现类 :黄焖鸡厨师
 */
public class HmJCooker implements ICooker{
    @Override
    public String cook() {
        return "制作黄焖鸡!";
    }
}
复制代码
public interface IProgrammer {
    String programme();
}

/**
 * 程序员的实现类:  京东的程序员
 */
public class JDProgrammer implements IProgrammer {
    @Override
    public String programme() {
        return "编写京东的网站!";
    }
}

复制代码

测试:

/**
 * 这就是为什么要使用 适配器模式
 * 这样的话  如果有很多接口的话,就会使得遍历非常的麻烦
 */
public class MyTest {
    public static void main(String[] args) {
        ICooker iCooker = new HmJCooker();
        IProgrammer iProgrammer = new JDProgrammer();

        //上报自己的职责  不能循环遍历
        System.out.println(iCooker.cook());
        System.out.println(iProgrammer.programme());
    }
}
复制代码

2、只定义一个适配器实现类

这种方式类似于多功能充电器,一个电源插头上接着多种类型的充电接口。用户在使用时需要使用电器接口与多功能充电器上的充电接口逐个进行对比,接口匹配,则可以充电。

22.png

代码:

public class WorkAdapter{

    public String work(Object worker) {
        String workContent = "";

        // 若传来的对象是厨师,就调用cook()方法
        if(worker instanceof ICooker){
            workContent = ((ICooker)worker).cook();
        }
        if(worker instanceof IProgrammer){
            workContent = ((IProgrammer)worker).programme();
        }
        return workContent;
    }
}

复制代码

测试类(可以实现循环遍历):

public class MyTest {
    public static void main(String[] args) {
        //这个是两个工作者
        ICooker iCooker = new HmJCooker();
        IProgrammer iProgrammer = new JDProgrammer();

        Object[] workers = {iCooker, iProgrammer};
        //创建设配器对象
        WorkAdapter adapter = new WorkAdapter();

        //让每个工种对象在设配器中进行匹配
        for (Object worker :  workers) {
            String workContent = adapter.work(worker);
            System.out.println(workContent);
        }
    }
}
复制代码

输出:

制作黄焖鸡!
编写京东的网站!
复制代码

3、为每个工种定义一个适配器类

这种用的最多。因为不同的电器需要不同的充电器。(很少上面这种组合充电器),而且SpringMVC里面也是用的这种方式。

3.png

代码:

/** 统一的 接口适配器 */
public interface IWorkerAdapter {
    String work(Object worker); //只能放Object,因为传进来的可以实现不同的接口

    boolean isSupport(Object worker);
}
复制代码

厨师的适配器:

public class CookerAdapter implements IWorkerAdapter{
    @Override
    public String work(Object obj) {
        return ((ICooker)obj).cook();
    }

    @Override
    public boolean isSupport(Object worker) {
        return (worker instanceof ICooker);
    }
}
复制代码

程序员的适配器:

public class ProgrammerAdapter implements IWorkerAdapter {
    @Override
    public String work(Object worker) {
        return ((IProgrammer)worker).programme();
    }

    @Override
    public boolean isSupport(Object worker) {
        return worker instanceof IProgrammer;
    }
}
复制代码

测试:

public class MyTest {

    static List<IWorkerAdapter> adapters;

    public static void main(String[] args) {
        //这个是两个工作者
        ICooker iCooker = new HmJCooker();
        IProgrammer iProgrammer = new JDProgrammer();

        Object[] workers = {iCooker, iProgrammer};

        //添加所有的适配器
        adapters = new ArrayList<>();
        adapters.add(new CookerAdapter());
        adapters.add(new ProgrammerAdapter());

        //让每个工种对象在设配器中进行匹配
        for (Object worker : workers) {
            IWorkerAdapter adapter = getAdapter(worker);   //   获取对应的适配器
            String workContent = adapter.work(worker);     //  对应的适配器进行对应的充电吧
            System.out.println(workContent);
        }
    }

    //获取指定的某个适配器
    static IWorkerAdapter getAdapter(Object worker) {
        for (IWorkerAdapter adapter : adapters) {
            if (adapter.isSupport(worker)) {
                return adapter;
            }
        }
        return null;
    }
}
复制代码

输出和上面一样。

三、总结

从这种角度来看,适配器不是冒充,而是实现统一管理



转载于:https://juejin.im/post/5d0b2b6b5188255fc6384df3

相关文章:

  • 【Flutter学习】基本组件之容器组件Container
  • Spring Boot - Web综合开发(转)
  • 总结一些常用功能源码
  • 16.04 下 ufw 防火墙的的开启、禁用、开放端口、关闭端口
  • 针对ASP.NET页面实时进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)...
  • POJ 1159 Palindrome (滚动数组 DP)
  • TCP服务端
  • IBatis.Net学习笔记九--动态选择Dao的设计分析
  • 强化学习基础:蒙特卡罗和时序差分
  • golang 浮点数 取精度的效率对比
  • OpenCV入门指南 人脸检测 haar分类器
  • MySQL主从延时这么长,要怎么优化?
  • 使用 NPOI 导出数据示例
  • WPF Browser 中如何获取当前路径(临时文件中)?
  • 10+优秀“分步引导”jQuery插件(转)
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • Android Studio:GIT提交项目到远程仓库
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • CSS居中完全指南——构建CSS居中决策树
  • gcc介绍及安装
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • iOS 颜色设置看我就够了
  • Javascripit类型转换比较那点事儿,双等号(==)
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • NSTimer学习笔记
  • PAT A1017 优先队列
  • php中curl和soap方式请求服务超时问题
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Redis 中的布隆过滤器
  • springboot_database项目介绍
  • Web Storage相关
  • zookeeper系列(七)实战分布式命名服务
  • 从setTimeout-setInterval看JS线程
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 基于组件的设计工作流与界面抽象
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 实习面试笔记
  • 使用common-codec进行md5加密
  • 手写一个CommonJS打包工具(一)
  • 微信小程序填坑清单
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​插件化DPI在商用WIFI中的价值
  • ​决定德拉瓦州地区版图的关键历史事件
  • #Linux(make工具和makefile文件以及makefile语法)
  • #QT(一种朴素的计算器实现方法)
  • $GOPATH/go.mod exists but should not goland
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (分布式缓存)Redis哨兵
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default