设计模式-适配器模式-注册器模式

设计模式-适配器模式-注册器模式

适配器模式

如果开发一个搜索中台,需要适配或接入不同的数据源,可能提供的方法参数和平台调用的方法参数不一致,可以使用适配器模式

image-20241129230331103

适配器模式通过封装对象将复杂的转换过程隐藏于幕后。 被封装的对象甚至察觉不到适配器的存在。 例如, 你可以使用一个将所有数据转换为英制单位 (如英尺和英里) 的适配器封装运行于米和千米单位制中的对象。

下面这段代码

postService,userService,imageService分别调用的方法逻辑相同参数不同,可使用接口统一调用

@Component
@Slf4j
public class SearchFacade {

    @Resource
    private PostService postService;

    @Resource
    private UserService userService;

    @Resource
    private ImageService imageService;

    @Resource
    ThreadPoolTaskExecutor threadPoolTaskExecutor;

    public SearchVo searchAll(@RequestBody SearchQueryRequest searchQueryRequest, HttpServletRequest httpServletRequest) {
        SearchVo searchVo = new SearchVo();
        if (searchQueryRequest == null) {
            return searchVo;
        }
        String searchText = searchQueryRequest.getSearchText();
        String searchType = searchQueryRequest.getSearchType();
        if (StringUtils.isBlank(searchType)) {
            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() -> {
                PostQueryRequest postQueryRequest = new PostQueryRequest();
                postQueryRequest.setSearchText(searchText);
                Page<PostVO> postVOPage = postService.listPostVoPage(postQueryRequest, httpServletRequest);
                return postVOPage;
            }, threadPoolTaskExecutor);

            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() -> {
                UserQueryRequest userQueryRequest = new UserQueryRequest();
                userQueryRequest.setUserName(searchText);
                Page<UserVO> userVOPage = userService.listUserVoPage(userQueryRequest);
                return userVOPage;
            }, threadPoolTaskExecutor);

            CompletableFuture<Page<Image>> imageTask = CompletableFuture.supplyAsync(() -> {
                ImageQueryRequest imageQueryRequest = new ImageQueryRequest();
                imageQueryRequest.setSearchText(searchText);
                Page<Image> imagePage = imageService.getImageByPage(imageQueryRequest);
                return imagePage;
            }, threadPoolTaskExecutor);

            CompletableFuture.allOf(postTask, userTask, imageTask);

            try {
                Page<PostVO> postVOPage = postTask.get();
                searchVo.setPostList(postVOPage.getRecords());
                Page<UserVO> userVOPage = userTask.get();
                searchVo.setUserList(userVOPage.getRecords());
                Page<Image> imagePage = imageTask.get();
                searchVo.setImageList(imagePage.getRecords());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        } else {
            SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(searchType);
            switch (searchTypeEnum) {
                case POST:
                    PostQueryRequest postQueryRequest = new PostQueryRequest();
                    postQueryRequest.setSearchText(searchText);
                    Page<PostVO> postVOPage = postService.listPostVoPage(postQueryRequest, httpServletRequest);
                    searchVo.setPostList(postVOPage.getRecords());
                    break;
                case USER:
                    UserQueryRequest userQueryRequest = new UserQueryRequest();
                    userQueryRequest.setUserName(searchText);
                    Page<UserVO> userVOPage = userService.listUserVoPage(userQueryRequest);
                    searchVo.setUserList(userVOPage.getRecords());
                    break;
                case IMAGE:
                    ImageQueryRequest imageQueryRequest = new ImageQueryRequest();
                    imageQueryRequest.setSearchText(searchText);
                    Page<Image> imagePage = imageService.getImageByPage(imageQueryRequest);
                    searchVo.setImageList(imagePage.getRecords());
                    break;
                default:
                    break;
            }
        }
        return searchVo;
    }
}

下面实现一个简单的适配器

新建一个数据源接口

/**
 * @author tuaofei
 * @description 查询数据源
 * @date 2024/11/29
 */
public interface SearchDataSource<T> {

    /**
     * 通用查询接口
     * @param searchText
     * @param current
     * @param pageSize
     * @return
     */
    Page<T> doSearch(String searchText, int current, int pageSize);
}

postService.listPostVoPage(postQueryRequest, httpServletRequest)

新增PostDataSource数据源

@Service
@Slf4j
public class PostDataSource implements SearchDataSource<PostVO> {

    @Resource
    private PostService postService;

    @Override
    public Page<PostVO> doSearch(String searchText, int current, int pageSize) {
        PostQueryRequest postQueryRequest = new PostQueryRequest();
        postQueryRequest.setSearchText(searchText);
        postQueryRequest.setCurrent(current);
        postQueryRequest.setPageSize(pageSize);
        //HttpServletRequest 这里没法获取,考虑改造接口或改造方法,根据具体情况判断
        Page<PostVO> postVOPage = postService.listPostVoPage(postQueryRequest, null);
        return postVOPage;
    }
}

新增UserDataSource 数据源

userService.listUserVoPage(userQueryRequest)

@Service
@Slf4j
public class UserDataSource implements SearchDataSource<UserVO> {

    @Resource
    private UserService userService;

    @Override
    public Page<UserVO> doSearch(String searchText, int current, int pageSize) {
        UserQueryRequest userQueryRequest = new UserQueryRequest();
        userQueryRequest.setUserName(searchText);
        Page<UserVO> userVOPage = userService.listUserVoPage(userQueryRequest);
        return userVOPage;
    }
}

新增ImageDataSource 数据源

imageService.getImageByPage(imageQueryRequest)

@Service
public class ImageDataSource implements SearchDataSource<Image> {

    @Resource
    private ImageService imageService;

    @Override
    public Page<Image> doSearch(String searchText, int current, int pageSize) {
        ImageQueryRequest imageQueryRequest = new ImageQueryRequest();
        imageQueryRequest.setSearchText(searchText);
        imageQueryRequest.setCurrent(current);
        imageQueryRequest.setPageSize(pageSize);
        Page<Image> imageByPage = imageService.getImageByPage(imageQueryRequest);
        return imageByPage;
    }
}

修改SearchFacade里面调用service的逻辑,这样就可以统一调用相同参数的方法,转换逻辑交给具体的数据源

@Component
@Slf4j
public class SearchFacade {

    @Resource
    private ImageDataSource imageDataSource;

    @Resource
    private PostDataSource postDataSource;

    @Resource
    private UserDataSource userDataSource;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    public SearchVo searchAll(@RequestBody SearchQueryRequest searchQueryRequest, HttpServletRequest httpServletRequest) {
        SearchVo searchVo = new SearchVo();
        if (searchQueryRequest == null) {
            return searchVo;
        }
        String searchText = searchQueryRequest.getSearchText();
        String searchType = searchQueryRequest.getSearchType();
        int current = searchQueryRequest.getCurrent();
        int pageSize = searchQueryRequest.getPageSize();
        if (StringUtils.isBlank(searchType)) {
            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() -> {
                Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current, pageSize);
                return postVOPage;
            }, threadPoolTaskExecutor);

            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() -> {
                Page<UserVO> userVOPage = userDataSource.doSearch(searchText, current, pageSize);
                return userVOPage;
            }, threadPoolTaskExecutor);

            CompletableFuture<Page<Image>> imageTask = CompletableFuture.supplyAsync(() -> {
                Page<Image> imagePage = imageDataSource.doSearch(searchText, current, pageSize);
                return imagePage;
            }, threadPoolTaskExecutor);

            CompletableFuture.allOf(postTask, userTask, imageTask);

            try {
                Page<PostVO> postVOPage = postTask.get();
                searchVo.setPostList(postVOPage.getRecords());
                Page<UserVO> userVOPage = userTask.get();
                searchVo.setUserList(userVOPage.getRecords());
                Page<Image> imagePage = imageTask.get();
                searchVo.setImageList(imagePage.getRecords());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        } else {
            SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(searchType);
            switch (searchTypeEnum) {
                case POST:
                    Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current, pageSize);
                    ;
                    searchVo.setPostList(postVOPage.getRecords());
                    break;
                case USER:
                    Page<UserVO> userVOPage = userDataSource.doSearch(searchText, current, pageSize);
                    searchVo.setUserList(userVOPage.getRecords());
                    break;
                case IMAGE:
                    Page<Image> imagePage = imageDataSource.doSearch(searchText, current, pageSize);
                    searchVo.setImageList(imagePage.getRecords());
                    break;
                default:
                    break;
            }
        }
        return searchVo;
    }
}

注册器模式

经过上面的修改,我们发现所有的调用查询方法参数都相同,而且都是通过调用实现了SearchDataSource接口的实现类来调用

我们可以简化下面的switch

SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(searchType);
            switch (searchTypeEnum) {
                case POST:
                    Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current, pageSize);
                    ;
                    searchVo.setPostList(postVOPage.getRecords());
                    break;
                case USER:
                    Page<UserVO> userVOPage = userDataSource.doSearch(searchText, current, pageSize);
                    searchVo.setUserList(userVOPage.getRecords());
                    break;
                case IMAGE:
                    Page<Image> imagePage = imageDataSource.doSearch(searchText, current, pageSize);
                    searchVo.setImageList(imagePage.getRecords());
                    break;
                default:
                    break;
            }

需要一个Map<String,SearchDataSource>来注册这些数据源,通过类型来获取对应的数据源,再调用查询方法

@Component
public class DataSourceRegistry {

    @Resource
    private ImageDataSource imageDataSource;

    @Resource
    private PostDataSource postDataSource;

    @Resource
    private UserDataSource userDataSource;

    private Map<String, SearchDataSource<T>> dataSourceMap;

    /**
     * 在依赖注入完成后,执行
     */
    @PostConstruct
    public void doInit() {
        dataSourceMap = new HashMap() {{
            put(SearchTypeEnum.POST.getValue(), postDataSource);
            put(SearchTypeEnum.USER.getValue(), userDataSource);
            put(SearchTypeEnum.IMAGE.getValue(), imageDataSource);
        }};
    }

    public SearchDataSource getDataSourceByType(String searchType) {
        if (dataSourceMap == null) {
            return null;
        }
        return dataSourceMap.get(searchType);
    }
}

在SearchFacade使用

@Component
@Slf4j
public class SearchFacade {

    @Resource
    private DataSourceRegistry dataSourceRegistry;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    public SearchVo searchAll(@RequestBody SearchQueryRequest searchQueryRequest, HttpServletRequest httpServletRequest) {
        SearchVo searchVo = new SearchVo();
        if (searchQueryRequest == null) {
            return searchVo;
        }
        String searchText = searchQueryRequest.getSearchText();
        String searchType = searchQueryRequest.getSearchType();
        int current = searchQueryRequest.getCurrent();
        int pageSize = searchQueryRequest.getPageSize();
        if (StringUtils.isBlank(searchType)) {
            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() -> {
                SearchDataSource postDataSource = dataSourceRegistry.getDataSourceByType(SearchTypeEnum.POST.getValue());
                Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current, pageSize);
                return postVOPage;
            }, threadPoolTaskExecutor);

            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() -> {
                SearchDataSource userDataSource = dataSourceRegistry.getDataSourceByType(SearchTypeEnum.USER.getValue());
                Page<UserVO> userVOPage = userDataSource.doSearch(searchText, current, pageSize);
                return userVOPage;
            }, threadPoolTaskExecutor);

            CompletableFuture<Page<Image>> imageTask = CompletableFuture.supplyAsync(() -> {
                SearchDataSource imageDataSource = dataSourceRegistry.getDataSourceByType(SearchTypeEnum.IMAGE.getValue());
                Page<Image> imagePage = imageDataSource.doSearch(searchText, current, pageSize);
                return imagePage;
            }, threadPoolTaskExecutor);

            CompletableFuture.allOf(postTask, userTask, imageTask);

            try {
                Page<PostVO> postVOPage = postTask.get();
                searchVo.setPostList(postVOPage.getRecords());
                Page<UserVO> userVOPage = userTask.get();
                searchVo.setUserList(userVOPage.getRecords());
                Page<Image> imagePage = imageTask.get();
                searchVo.setImageList(imagePage.getRecords());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        } else {
            SearchDataSource<?> dataSource = dataSourceRegistry.getDataSourceByType(searchType);
            //可以使用公共的返回对象,类型使用泛型
            Page<?> page = dataSource.doSearch(searchText, current, pageSize);
            List<?> records = page.getRecords();
            searchVo.setDataList(records);
        }
        return searchVo;
    }
}

在SearchVo新建公共返回对象

@Data
public class SearchVo implements Serializable {

    private List<PostVO> postList;
    private List<Image> imageList;
    private List<UserVO> userList;

    /**
     * 公共返回对象
     */
    private List<?> dataList;
}

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

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

相关文章

SpringBoot实战(三十二)集成 ofdrw,实现 PDF 和 OFD 的转换、SM2 签署OFD

目录 一、OFD 简介1.1 什么是 OFD&#xff1f;1.2 什么是 版式文档&#xff1f;1.3 为什么要用 OFD 而不是PDF&#xff1f; 二、ofdrw 简介2.1 定义2.2 Maven 依赖2.3 ofdrw 的 13 个模块 三、PDF/文本/图片 转 OFD&#xff08;ofdrw-conterver&#xff09;3.1 介绍&#xff1a…

Opencv+ROS实现摄像头读取处理画面信息

一、工具 ubuntu18.04 ROSopencv2 编译器&#xff1a;Visual Studio Code 二、原理 图像信息 ROS数据形式&#xff1a;sensor_msgs::Image OpenCV数据形式&#xff1a;cv:Mat 通过cv_bridge()函数进行ROS向opencv转换 cv_bridge是在ROS图像消息和OpenCV图像之间进行转…

【MySQL — 数据库基础】MySQL的安装与配置 & 数据库简单介绍

数据库基础 本节目标 掌握关系型数据库&#xff0c;数据库的作用掌握在Windows和Linux系统下安装MySQL数据库了解客户端工具的基本使用和SQL分类了解MySQL架构和存储引擎 1. 数据库的安装与配置 1.1 确认MYSQL版本 处理无法在 cmd 中使用 mysql 命令的情况&a…

shell编程基础笔记

目录 echo改字体颜色和字体背景颜色 bash基本功能&#xff1a; 运行方式&#xff1a;推荐使用第二种方法 变量类型 字符串处理&#xff1a; 条件判断&#xff1a;&#xff08;使用echo $?来判断条件结果&#xff0c;0为true&#xff0c;1为false&#xff09; 条件语句&a…

maxun爬虫工具docker搭建

思路来源开源无代码网络数据提取平台Maxun 先把代码克隆到本地&#xff08;只有第一次需要&#xff09; git clone https://github.com/getmaxun/maxun.git 转到maxun目录 cd maxun 启动容器 docker-compose --env-file .env up -d 成功启动六个容器 网址 http://local…

redis揭秘-redis01-redis单例与集群安装总结

文章目录 【README】【1】安装单机【1.1】安装环境【1.2】安装步骤 【2】redis集群主从模式配置【2.1】集群架构【2.2】redis集群主从模式搭建步骤【2.3】redis集群主从模式的问题&#xff08;单点故障问题&#xff09; 【3】redis集群哨兵模式配置【3.1】集群架构【3.2】redis…

构建高可用系统设计OpenStack、Docker、Mesos和Kubernetes(简称K8s)

如果构建高可用、高并发、高效运维的大型系统 大型系统架构设计包括业务层设计、服务层设计、基础架层设计、存储层设计、网络层协同设计来完成。 一、业务层 根据主要业务范畴的分类和特征提取&#xff0c;抽象出独立的业务系统&#xff0c;分别统计系统的用户角色群体、访…

mrRobot解题过程

一、靶场环境需要桥接网络 不建议使用校园网&#xff0c;因为使用校园网进行主机探索的时候会出现数不完的主机。 arp-scan -l若是流量少只能用校园网&#xff0c;便在这里看靶机ip 二、端口扫描 我习惯用fscan了&#xff08;需要自己安装&#xff09;&#xff0c;你们用nma…

解决“ VMware Tools for Windows Vista and later“报错问题

今天&#xff0c;在Win7虚拟机上安装VMware Tools&#xff0c;报"VMware Tools for Windows Vista and later"证书错误&#xff0c;如图(1)所示&#xff1a; 图(1) 虚拟机报" VMware Tools for Windows Vista and later"证书错误 问题原因&#xff1a;VMwa…

C-操作符

操作符种类 在C语言中&#xff0c;操作符有以下几种&#xff1a; 算术操作符 移位操作符 位操作符 逻辑操作符 条件操作符 逗号表达式 下标引用&#xff0c;函数调用 拓展&#xff1a;整型提升 我们介绍常用的几个 算术操作符 &#xff08;加&#xff09;&#xff…

时频转换 | Matlab基于S变换S-transform一维数据转二维图像方法

目录 基本介绍程序设计参考资料获取方式基本介绍 时频转换 | Matlab基于S变换S-transform一维数据转二维图像方法 程序设计 clear clc % close all load x.mat % 导入数据 x =

物联网——WatchDog(监听器)

看门狗简介 独立看门狗框图 看门狗原理&#xff1a;定时器溢出&#xff0c;产生系统复位信号&#xff1b;若定时‘喂狗’则不产生系统复位信号 定时中断基本结构&#xff08;对比&#xff09; IWDG键寄存器 独立看门狗超时时间 WWDG(窗口看门狗) WWDG特性 WWDG超时时间 由于…

Socket编程:UDP网络编程项目

目录 一、回显服务器 二、翻译器 三、聊天室 一、回显服务器 项目介绍&#xff1a;使用UDPIPv4协议进行Linux网络编程&#xff0c;实现回显服务器和客户端 功能介绍&#xff1a;客户端发送数据&#xff0c;经过服务端再返回到客户端&#xff0c;输出数据 源代码&#xff1…

Hbase2.2.7集群部署

环境说明 准备三台服务器&#xff0c;分别为&#xff1a;bigdata141&#xff08;作为Hbase主节点&#xff09;、bigdata142、bigdata143确保hadoop和zookeeper集群都先启动好我这边的hadoop版本为3.2.0&#xff0c;zookeeper版本为3.5.8 下载安装包 下载链接&#xff1a;In…

STM32 BootLoader 刷新项目 (十二) Option Byte之FLASH_OPTCR-命令0x58

STM32 BootLoader 刷新项目 (十二) Option Byte之FLASH_OPTCR-命令0x58 STM32F407芯片的OPTION Byte全面解析 STM32F407芯片是STMicroelectronics推出的一款功能强大的微控制器&#xff0c;广泛应用于工业控制、通信和消费电子等领域。其中&#xff0c;OPTION Byte&#xff0…

Matlab 绘制雷达图像完全案例和官方教程(亲测)

首先上官方教程链接 polarplothttps://ww2.mathworks.cn/help/matlab/ref/polarplot.html 上实例 % 定义角度向量和径向向量 theta linspace(0, 2*pi, 5); r1 [1, 2, 1.5, 2.5, 1]; r2 [2, 1, 2.5, 1.5, 2];% 绘制两个雷达图 polarplot(theta, r1, r-, LineWidth, 2); hold …

【C/C++】内存管理详解:从new/delete到智能指针的全面解析

文章目录 更多文章C/C中的传统内存管理方式new和delete运算符malloc和free函数传统内存管理的弊端 智能指针的崛起智能指针的定义与作用C11引入的标准智能指针 详解C标准智能指针std::unique_ptr特点使用方法适用场景 std::shared_ptr特点使用方法适用场景 std::weak_ptr特点使…

Python实现2048小游戏

2048是一个单人益智游戏&#xff0c;目标是移动和合并数字&#xff0c;以达到2048。 1. 实现效果 Python实现2048小游戏 2. 游戏规则 简单地理解一下规则 基本规则&#xff1a; 4x4棋盘&#xff0c;每个格可包含一个2的倍数的数字&#xff0c;初始时为空&#xff0c;表示0。…

Wireshark常用功能使用说明

此处用于记录下本人所使用 wireshark 所可能用到的小技巧。Wireshark是一款强大的数据包分析工具&#xff0c;此处仅介绍常用功能。 Wireshark常用功能使用说明 1.相关介绍1.1.工具栏功能介绍1.1.1.时间戳/分组列表概况等设置 1.2.Windows抓包 2.wireshark过滤器规则2.1.wiresh…

像素流送api ue多人访问需要什么显卡服务器

关于像素流送UE推流&#xff0c;在之前的文章里其实小芹和大家聊过很多&#xff0c;不过今天偶然搜索发现还是有很多小伙伴&#xff0c;在搜索像素流送相关的问题&#xff0c;搜索引擎给的提示有这些。当然这些都是比较短的词汇&#xff0c;可能每个人真正遇到的问题和想获取的…