设计模式-策略模式【实战】

设计模式-策略模式【实战】

通常面试题:项目中你认为设计好的地方有哪些,项目中的设计模式是怎么用的?为什么要用设计模式…
通常这样的问题,就开始自我吹嘘,解耦,高内聚低耦合啥的… 面试官一脸黑
废话少说上设计模式,讲讲我的理解。

策略模式:
策略模式允许你定义一系列算法,将每个算法封装起来,并使它们可以互相替换。在这种情况下,每个查询类型可以被视为一个不同的策略,它们可以根据查询类型的不同而执行不同的查询操作。

场景:

举例说明:
公司项目不方便举例,这边用查询图书举例。
1,有三个模块【分别是:小学、初中、高中】,分别要查询分别对应书,以及课本详情
2,操作对象都是书,可能就是dto的参数不同,数据类型是相同的
3,通常设计dto用于接收参数,加一个字段 queryType 用于区分不同的查询类型

写法一:【未用设计模式之前】

controller

    @Autowired
    private BookService bookService;
    @PostMapping("/queryBookListByDto")
    public List<BookVo> queryBookListByDto(@RequestBody BookDto dto){
        return bookService.queryBookListByDto(dto);
    }

service

/**
 * @author psd
 */
public interface BookService {

    /**
     * 根据dto查询书的集合
     *
     * @param dto
     *            dto对象
     * @return 书的集合
     */
    List<BookVo> queryBookListByDto(BookDto dto);
}

serviceImpl

    @Autowired
    private Map<Integer, QueryStrategy> queryStrategyMap;
    
    @Override
    public List<BookVo> queryBookListByDto(BookDto dto) {
    List<BookVo> bookVoList = new ArrayList<>();
        switch (dto.getQueryType()){
            case 1:
                // 执行查询逻辑
                bookVoList = queryStrategyMap.queryBookListByDto(BookDto dto);
                return ;
            case 2:
                // 执行查询逻辑
                bookVoList = queryStrategyMap.queryBookListByDto(BookDto dto);
                return ;
            case 3:
                // 执行查询逻辑
                bookVoList = queryStrategyMap.queryBookListByDto(BookDto dto);
                return ;
            default:
        }
        return bookVoList ;
    }

dto

/**
 * @author psd
 */
@Data
public class BookDto {

    /**
     * 作者名字
     */
    private String authName;

    /**
     * 查询的类型 1:小学 2:中学 3:高中 4:大学
     */
    private Integer queryType;

}

写法二:【策略模式书写】

步骤:
1,定义一个接口用来表示不同的查询策略
2,每种查询都实现这个接口,重写里面的方法,实现不同的查询策略
3,将所有的策略类注入到一个Map中,以便根据查询类型来选择相应的策略
4,使用的时候获取指定的策略,执行查询方法

1,定义一个接口用来表示不同的查询策略

/**
 * @author psd
 */

public interface QueryStrategy {

    /**
     * 查询书籍
     * 
     * @param dto
     *            查询条件
     * @return 书的集合
     */
    List<BookEntity> executeQuery(BookDto dto);

}

2、每种查询都实现这个接口,重写里面的方法,实现不同的查询策略

小学

/**
 * @author psd 小学
 */
@Service
public class PrimarySchool implements QueryStrategy {

    @Autowired
    private BookMapper bookMapper;
    @Override
    public List<BookEntity> executeQuery(BookDto dto) {
        // TODO:小学的看的书
        return null;
    }
}

初中

/**
 * @author psd 初中
 */
@Service
public class JuniorHighSchool implements QueryStrategy {

    @Autowired
    private BookMapper bookMapper;

    @Override
    public List<BookEntity> executeQuery(BookDto dto) {
        return null;
    }
}

高中

/**
 * @author psd 高中
 */
@Service
public class SeniorHighSchool implements QueryStrategy {

    @Autowired
    private BookMapper bookMapper;
    @Override
    public List<BookEntity> executeQuery(BookDto dto) {
        return null;
    }
}

3、将所有的策略类注入到一个Map中,以便根据查询类型来选择相应的策略

/**
 * @author psd 执行查询策略配置
 */
@Configuration
public class ExecuteQueryStrategyConfig {

    @Autowired
    private JuniorHighSchool juniorHighSchool;

    @Autowired
    private SeniorHighSchool seniorHighSchool;

    @Autowired
    private PrimarySchool primarySchool;

    @Bean
    public Map<Integer, QueryStrategy> queryStrategyMap() {
        return Map.of(
                1, juniorHighSchool,
                2, seniorHighSchool,
                3, primarySchool
        );
    }

}

4、使用的时候获取指定的策略,执行查询方法

/**
 * @author psd
 */
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private Map<Integer, QueryStrategy> queryStrategyMap;

    @Override
    public List<BookVo> queryBookListByDto(BookDto dto) {
       // 获取指定的查询策略
        QueryStrategy queryStrategy = queryStrategyMap.get(dto.getQueryType());
        // 执行查询方法
        List<BookEntity> entities = queryStrategy.executeQuery(dto);
        // 数据类型转换
        return entities.stream().map(x -> {
            BookVo vo = new BookVo();
            BeanUtils.copyProperties(x, vo);
            return vo;
        }).collect(Collectors.toList());
    }
}

谈谈我的理解:

1,为啥要用到设计模式,主要是解耦,用我自己话,让代码看起来简洁,高内聚低耦合,少用if else 或者switch…
2,后面如果再有类似的查询,直接编写实现类去实现查询策略接口,编写自己内部的查询逻辑即可,减少代码的依赖性
3,编写高质量的代码

注意事项:

1,使用策略模式时候,在传参时候要做参数校验比如queryTyep查询类型,必须是哪几个值
2,在实现策略的实现类里面,需要使用mapper 或者service的时候,要考虑到是否放到spring容器里面,避免null的问题。

喜欢我的文章的话,点个阅读或者点个点赞,是我编写博客的动力,持续更新中 ing…

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
回答:Spring Boot是一个用于快速开发基于Spring框架的Java应用程序的框架。在Spring Boot中,可以使用设计模式来实现各种功能。其中一个常见的设计模式策略模式策略模式允许在运行时选择不同的算法或行为。在Spring Boot中,可以通过使用依赖注入和IoC容器来实现策略模式。首先,在pom.xml文件中引入所需的依赖项,包括Spring Boot的starter和其他所需的库。然后,通过使用@Autowired注释将CommandFactory注入到测试类中。最后,可以在合适的地方使用CommandFactory来执行相应的算法或行为。在Spring的IoC容器中,当一个接口有多个实现类时,Spring会自动将这些实现类注入到一个Map中,以便根据需要选择相应的实现类。这样,我们可以在Spring Boot应用程序中使用策略模式来实现各种功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Springboot 使用管道设计模式 , 实践案例玩一玩](https://blog.csdn.net/qq_35387940/article/details/127315766)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [实战讲解,原来是用 SpringBoot 实现策略模式可以这么简单](https://blog.csdn.net/weixin_71682097/article/details/125331750)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值