0

    使用注册模式 + 门面模式优化聚合搜索引擎代码

    2023.04.15 | admin | 134次围观

    使用注册模式 + 门面模式优化聚合搜索引擎代码什么是聚合搜索

    最近在做一个搜索引擎的小demo

    此类系统有很多案例,比如bing的搜索,你在搜索框中搜你想要搜索的文字,根据下方的tab栏进行切换,可以搜索到不同种类的东西。

    再比如说b站的搜索引擎

    会根据搜索出来的词,提供不同种类的搜索结果。

    设计分析

    其实,对于此类搜索引擎,每一个标签的切换,都意味着在不同的数据源中进行搜索。

    如果每一个数据源的调用都是一个新的接口的话搜索引擎主要有哪些模式,前端同学会遇到以下两个问题:

    所以,作为一个合格的后端,我们要做的应该是减少前端同学对于请求内容的整理,尽量做到一个接口解决完所有问题。

    门面模式

    门面模式就是为了这个场景而生的。

    什么是门面模式?

    门面模式要求子系统的外部和内部的通信,必须要通过一个统一的门面来进行。

    就好像是一个商品售卖员,你要香烟,它会给你,你要水搜索引擎主要有哪些模式,它也会给你一样。你要做的只是向她去提出你想要的东西。

    门面模式相当于给你提供了一个高层次的接口,使得子系统易于调用。

    使用注册模式 + 门面模式优化聚合搜索引擎代码

    对于前端同学来说,无疑是大大减轻了他们的负担。从代码层面上来说,规范了请求路径,传参。易于调用。

    请求路径:/api/search/page/vo
    {
        type:"图片 || 文章 || 热榜 ||"
        searchText:"",
        current:
        pageSize
    }
    复制代码

    后端实现门面模式1.设计门面类

    设计SearchFacade类。(facade 就是门面的意思)

    这个类里面写searchAll的方法。统一传入参数,实现搜索到的数据返回。

    @Component
    @Slf4j
    public class SearchFacade {
    ​
    ​
    ​
        @PostMapping
        public SearchVO searchAll(@RequestBody SearchQueryRequest searchQueryRequest) {
           
        }
    ​
    }
    复制代码

    2.设置数据源接口

    public interface DataSource<T> {
    ​
        Page search(String searchText, long current, long pageSize);
    ​
    }
    ​
    复制代码

    3.实现数据源接口

    @Component
    public class JueArticleDatasource implements DataSource{
    ​
        @Resource
        private JueArticleService jueArticleService;
    ​
    ​
        @Override
        public Page search(String searchText, long current, long pageSize) {
            return jueArticleService.searchArticle(searchText,current,pageSize);
        }
    }
    ​
    复制代码

    @Component
    public class PictureDataSource implements DataSource{
    ​
        @Resource
        private PictureService pictureService;
    ​
    ​
        @Override
        public Page search(String searchText, long current, long pageSize) {
            return pictureService.searchPicture(searchText,current,pageSize);
        }
    }
    ​
    复制代码

    @Component
    public class ArticleDataSource implements DataSource{
    ​
        @Resource
        private PostService postService;
    ​
    ​
        @Override
        public Page search(String searchText, long current, long pageSize) {
            PostQueryRequest postQueryRequest = new PostQueryRequest();
            postQueryRequest.setSearchText(searchText);
            Page postPage = postService.page(new Page<>(current, pageSize),
                    postService.getQueryWrapper(postQueryRequest));
            return postService.getPostVOPage(postPage, null);
        }
    }
    复制代码

    注意,这里由于service里面的方法传的值不一样,我们就可以在datasource的实现类中,对参数进行适配,这也是适配器模式的思想体现。

    4.利用注册模式注册数据源

    @Component
    public class DataSourceRegistry {
    ​
        @Resource
        private ArticleDataSource articleDataSource;
    ​
        @Resource
        private PictureDataSource pictureDataSource;
    ​
        @Resource
        private JueArticleDatasource jueArticleDatasource;
    ​
    ​
        private Map<DataSourceTypeEnum,DataSource> dataSourceMap;
    ​
    ​
        @PostConstruct
        public void initDataSourceMap(){
            dataSourceMap = new HashMap<>();
            dataSourceMap.put(DataSourceTypeEnum.Article,articleDataSource);
            dataSourceMap.put(DataSourceTypeEnum.JueArticle,jueArticleDatasource);
            dataSourceMap.put(DataSourceTypeEnum.Picture,pictureDataSource);
        }
        /**
         * 这里也有策略模式的思想体现,根据type找到相应的数据源服务
         **/
        public DataSource getDataSourceByType(String type){
            DataSourceTypeEnum typeEnum = DataSourceTypeEnum.getEnumByValue(type);
            return dataSourceMap.get(typeEnum);
        }
    }
    ​
    复制代码

    5.在search门面中选择相应的数据源进行查询。

    @Component
    @Slf4j
    public class SearchFacade {
    ​
    ​
        @Resource
        private DataSourceRegistry dataSourceRegistry;
    ​
    ​
        @PostMapping
        public SearchVO searchAll(@RequestBody SearchQueryRequest searchQueryRequest) {
            SearchVO searchVO = new SearchVO();
            String searchText = searchQueryRequest.getSearchText();
            long current = searchQueryRequest.getCurrent();
            long pageSize = searchQueryRequest.getPageSize();
            String type = searchQueryRequest.getType();
    ​
            DataSource dataSource = dataSourceRegistry.getDataSourceByType(type);
            Page search = dataSource.search(searchText, current, pageSize);
            searchVO.setDataList(search.getRecords());
            return searchVO;
        }
    ​
    }
    复制代码

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    标签: 代码优化
    发表评论