基于Spring自动注入的策略模式

xiaoxiao2025-10-02  4

一 背景:

比如我现在要一个具体的活动进行crud但我的活动分成多种活动模式如:秒杀,折扣等,这样就不能统一对具体活动进行crud

二 传统方式:

1,我就要通过创建不同活动类型的service如:ISeckillActivityService,IDiscountActivityService等

2,在要进行crud的地方,通过活动的类型去做if判断/switch,来调用相应的service,再进行crud操作

缺点: 这样代码中会有大量的if或者switch

三 解决方式

基于Spring自动注入的策略模式

1> 类结构关系图

如图:由于IDiscountActivityService 和ISeckillActivityService 都继承了BaseActivityService , spring提供了根据类型注入bean的特性,我们可以将同一种类型的bean注入到一个map中而具体的service(bean)的key为其id

2> 具体java类

策略模式关键类

BaseActivityService需要统一操作的接口方法 /** * @description: 活动基础service * @author: kismet * @create: 2018-10-25 11:48 */ public interface BaseActivityService { /** * 添加活动 * @return */ Long addActivity(ActivityVo vo); /** * 更新活动 * @return */ void upDateActivity(ActivityVo vo); } IDiscountActivityService 折扣活动接口 /** * @description:折扣活动 * @author: kismet * @create: 2018-10-25 11:50 */ public interface IDiscountActivityService extends BaseActivityService { } ISeckillActivityService 秒杀活动接口 /** * @description: 秒杀活动 * @author: kismet * @create: 2018-10-25 11:50 */ public interface ISeckillActivityService extends BaseActivityService { } DiscountActivityServiceImpl 折扣活动实现类 /** * @description: * @author: kismet * @create: 2018-10-25 11:58 */ @Service("discountActivityService") public class DiscountActivityServiceImpl implements IDiscountActivityService { @Override public Long addActivity(ActivityVo vo) { System.out.println("折扣活动添加"); return -1L; } @Override public void upDateActivity(ActivityVo vo) { System.out.println("折扣活动更新"); } } SeckillActivityServiceImpl 秒杀活动实现类 /** * @description: * @author: kismet * @create: 2018-10-25 11:59 */ @Service("seckillActivityService") public class SeckillActivityServiceImpl implements ISeckillActivityService { @Override public Long addActivity(ActivityVo vo) { System.out.println("秒杀活动添加"); return -2L; } @Override public void upDateActivity(ActivityVo vo) { System.out.println("秒杀活动更新"); } }

其他相关类

ActivityTypeEnum 活动类型枚举 /** * @description: 活动类型枚举 * @author: kismet * @create: 2018-10-08 9:14 */ @Getter public enum ActivityTypeEnum { /** * 1,秒杀活动;service的key即为seckillActivityService */ SECKILL(1, "秒杀活动", "seckillActivityService"), /** * 2,折扣活动;service的key即为discountActivityService */ DISCOUNT(2, "折扣活动", "discountActivityService"); private Integer key; private String desc; /** * 对应的service实现类key */ private String service; ActivityTypeEnum(Integer key, String desc, String service) { this.key = key; this.desc = desc; this.service = service; } public static ActivityTypeEnum getEnumByType(Integer key) { for (ActivityTypeEnum item : ActivityTypeEnum.values()) { if (item.getKey().equals(key)) { return item; } } throw new RuntimeException("通过key获取枚举类异常"); } } ActivityVo活动基本信息类 ** * @description: 活动基本信息类 * @author: kismet * @create: 2018-10-25 12:45 */ @Getter @Setter public class ActivityVo { /** * 活动id */ private Long id; /** * 活动类型:1,秒杀活动;2折扣活动 */ private Integer activityType; } MyTestController 测试类 /** * @description: 测试controller * @author: kismet * @create: 2018-10-25 12:54 */ @RestController public class MyTestController { //注入BaseActivityService子类的service,key为子类service的key @Autowired private Map<String,BaseActivityService> activityServiceMap; @RequestMapping("test") public void test(ActivityVo vo){ vo.setActivityType(ActivityTypeEnum.SECKILL.getKey());//设置活动类型为直降测试用 //1,根据活动对象获取活动类型, Integer activityType = vo.getActivityType(); //2,获取活动对象的service的key String servicekey = ActivityTypeEnum.getEnumByType(activityType).getService(); //3,获取对应的活动service BaseActivityService service = activityServiceMap.get(servicekey); //4,调用具体活动service的方法;add或者update等等 service.addActivity(vo); service.upDateActivity(vo); } }

测试和小结:

1> 测试

当测试类中的vo的活动类型为1,秒杀活动时, 即 vo.setActivityType(ActivityTypeEnum.SECKILL.getKey()); 控制台输出:

秒杀活动添加 秒杀活动更新

当测试类中的vo的活动类型为1,秒杀活动时,控制台输出: 即vo.setActivityType(ActivityTypeEnum.DISCOUNT.getKey()); 控制台输出:

折扣活动添加 折扣活动更新

小结:

1>该策略方式借助于spring的ioc方式,将同一类型的bean注入到一个Map中2>将bean的id存到对应枚举中,3>通过活动的类型获取到具体的枚举,4>这样就可以通过枚举去得到bean的id,从而从Map中取到具体的bean5>然后再调用bean的方法
转载请注明原文地址: https://www.6miu.com/read-5037258.html

最新回复(0)