经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
Java中常用的设计模式之策略模式详解
来源:jb51  时间:2022/2/28 8:51:25  对本文有异议

优点

1.算法可以自由切换。

2.避免使用多重条件判断。

3.扩展性良好。

缺点

1.策略类会增多。

2.所有策略类都需要对外暴露。

使用场景

1.如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。

2.一个系统需要动态地在几种算法中选择一种。

3.如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

一、实现方式

假设一个场景,我们在电商系统中,订单分为很多种,例如:普通订单,秒杀订单,拼团订单等等。我们需要创建一个订单的时候,由于订单的类型不同,我们需要根据订单的类型执行不同的业务逻辑。

1、订单类型枚举类

  1. package com.asurplus.common.strategy;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Getter;
  4. /**
  5. * 订单类型枚举类
  6. */
  7. @Getter
  8. @AllArgsConstructor
  9. public enum OrderTypeEnum {
  10. COMMON(1001, "普通订单"),
  11. SECKILL(1002, "秒杀订单"),
  12. SPELL(1003, "拼团订单");
  13. int type;
  14. String desc;
  15. }

我们的订单分为三种,普通订单,秒杀订单,拼团订单。

2、订单处理接口

  1. package com.asurplus.common.strategy;
  2. /**
  3. * 订单处理接口
  4. */
  5. public interface OrderService {
  6. /**
  7. * 创建订单
  8. *
  9. * @return
  10. */
  11. void createOrder();
  12. /**
  13. * 获取订单类型
  14. *
  15. * @return
  16. */
  17. OrderTypeEnum type();
  18. }

3、普通订单处理器

  1. package com.asurplus.common.strategy;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.stereotype.Service;
  4. /**
  5. * 普通订单处理器
  6. */
  7. @Slf4j
  8. @Service
  9. public class CommonOrderServiceImpl implements OrderService {
  10. @Override
  11. public void createOrder() {
  12. log.info("创建 普通订单");
  13. }
  14. @Override
  15. public OrderTypeEnum type() {
  16. return OrderTypeEnum.COMMON;
  17. }
  18. }

4、秒杀订单处理器

  1. package com.asurplus.common.strategy;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.stereotype.Service;
  4. /**
  5. * 秒杀订单处理器
  6. */
  7. @Slf4j
  8. @Service
  9. public class SeckillOrderServiceImpl implements OrderService {
  10. @Override
  11. public void createOrder() {
  12. log.info("创建 秒杀订单");
  13. }
  14. @Override
  15. public OrderTypeEnum type() {
  16. return OrderTypeEnum.SECKILL;
  17. }
  18. }

5、拼团订单处理器

  1. package com.asurplus.common.strategy;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.stereotype.Service;
  4. /**
  5. * 拼团订单处理器
  6. */
  7. @Slf4j
  8. @Service
  9. public class SpellOrderServiceImpl implements OrderService {
  10. @Override
  11. public void createOrder() {
  12. log.info("创建 拼团订单");
  13. }
  14. @Override
  15. public OrderTypeEnum type() {
  16. return OrderTypeEnum.SPELL;
  17. }
  18. }

6、下单管理器

  1. package com.asurplus.common.strategy;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.stereotype.Component;
  4. import java.util.List;
  5. import java.util.Optional;
  6. /**
  7. * 订单管理器
  8. */
  9. @Component
  10. public class OrderManager {
  11. /**
  12. * Autowired 注解的强大之处
  13. */
  14. @Autowired
  15. private List<OrderService> orderServices;
  16. /**
  17. * 创建订单
  18. *
  19. * @param type 订单类型
  20. * @return
  21. */
  22. public void createOrder(int type) {
  23. /**
  24. * 根据订单类型,找到对应的处理器
  25. */
  26. Optional<OrderService> any = orderServices.stream().filter(f -> f.type().getType() == type).findAny();
  27. /**
  28. * 没有对应的处理器
  29. */
  30. if (!any.isPresent()) {
  31. throw new RuntimeException("没有找到相应的订单实现");
  32. }
  33. // 创建订单
  34. any.get().createOrder();
  35. }
  36. }

这里就能体现出 @Autowired 的强大之处,可以一次性自动注入多个对象。根据订单类型,选出对应的处理器来处理该订单。

二、测试

1、引入依赖

  1. <!-- 测试依赖 -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-test</artifactId>
  5. </dependency>

2、测试用例

  1. package com.asurplus.common.strategy;
  2. import org.junit.Test;
  3. import org.junit.runner.RunWith;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import org.springframework.test.context.junit4.SpringRunner;
  7. /**
  8. * 策略模式
  9. */
  10. @RunWith(SpringRunner.class)
  11. @SpringBootTest
  12. public class TestMain {
  13. @Autowired
  14. private OrderManager orderManager;
  15. @Test
  16. public void test() {
  17. // 创建 秒杀订单
  18. orderManager.createOrder(OrderTypeEnum.SECKILL.getType());
  19. }
  20. }

输出结果

在这里插入图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注w3xue的更多内容!   

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号