真实场景运用Springboot +策略模式

1.简介

在真实开发中,我们经常需要处理不同类型的对象,但是对他们的操作是相同或者类似的,在这种场景下,策略模式就派上用场啦,我之前也看过不少文章,但是看的云里雾里,看完还是不知道怎么用,那么,在这篇文章中,我也不写理论的东西,直接上代码,和大家一起交流,一起学习。

2.模拟场景

我们在系统中展示了一些图片、视频、活动等,当用户点击之后,我们需要把这个视频或者这个活动的浏览量增加1,同时,这些数据都存储在各自的数据表中,也就是说,我们在更新浏览量时,需要更新不同的表,你不可能用if else 去搞吧,哈哈哈。这就是对不同的类型进行相同的操作,那就很契合策略模式呀。哈哈哈,直接上代码吧。

3. Contorller层

我们先看一下控制层,这是接口的入口,这个没什么说的,就是常规代码:

// ViewCountController.java

@Validated
@RestController
@RequestMapping("/view-count")
@RequiredArgsConstructor
public class ViewCountController {
    private final ViewCountContext viewCountContext;

    @PostMapping("/increase")
    @Operation(summary = "浏览量递增", description = "该接口用于用户点击相应业务时,增加浏览量")
    public GenericResponseEntity<Boolean> increaseViewCount(@RequestBody @Valid ViewCountIncreaseDto request) {
        viewCountContext.increaseViewCount(request);
        return GenericResponseEntity.success(true);
    }
}

简单说一下其中的注解,@Operation 这个是OpenSwagger的注解,其他的就是常规注解啦。

4.定义浏览量类型枚举ViewCountTypeEnum 方便统一管理

这个枚举类是干啥的呢? 我们不是有很多类型的业务嘛,这个枚举就是用来定义不同的业务类型,然后开放一个业务类型的字段给前端,前端就通过这个字段告诉我们用户点击的是哪个业务,后端就可以根据传递过来的值拿到对应的业务枚举,然后就可以根据策略执行具体的代码啦。

// ViewCountTypeEnum.java

@Getter
public enum ViewCountTypeEnum {
    ACTIVITY_VIEW("activityView", "活动浏览量"),

    PICTURE_VIEW("pictureView", "图片浏览量"),

    VIDEO_VIEW("videoView", "视频浏览量");

    private final String type;

    private final String desc;

    ViewCountTypeEnum(String type, String desc) {
        this.type = type;
        this.desc = desc;
    }

    public String getType() {
        return this.type;
    }

    public String getDesc() {
        return this.desc;
    }

    public static ViewCountTypeEnum getCommentTypeEnum(String type) {
        for (ViewCountTypeEnum viewCountTypeEnum : ViewCountTypeEnum.values()) {
            if (viewCountTypeEnum.getType().equals(type)) {
                return viewCountTypeEnum;
            }
        }
        throw new IllegalArgumentException("无效的type值: " + type);
    }
}

5. 定义一个接口ViewCountStrategy 作为浏览量递增策略的通用接口:

这儿有两个接口,一个是浏览量递增策略的通用接口,一个是获取具体业务枚举的接口。

// ViewCountStrategy.java

public interface ViewCountStrategy {
     // 通用接口
    void increaseViewCount(Long id);
    // 根据前端传递的值,获取具体的类型
    String getViewCountType();
}

6.具体的浏览量递增策略由实现了 ViewCountStrategy 接口的具体业务类来完成,如下三个类型的业务

下面就是具体业务执行 浏览量递增的逻辑啦。

6.1.图片类型

public class PictureViewCountStrategy implements ViewCountStrategy {
    @Resource
    private SharedEStationsPictureMapper pictureMapper;

    @Override
    public void increaseViewCount(Long id) {
        SharedEStationsPicture picture = pictureMapper.selectById(id);

        if (null != picture) {
            picture.setViews(picture.getViews() + 1);

            pictureMapper.updateById(picture);
        }
    }

    @Override
    public String getViewCountType() {
        return ViewCountTypeEnum.PICTURE_VIEW.getType();
    }
}

6.2.视频类型

@Component
public class VideoViewCountStrategy implements ViewCountStrategy {
    @Resource
    private SharedEStationsVideoMapper videoMapper;

    @Override
    public void increaseViewCount(Long id) {
        SharedEStationsVideo video = videoMapper.selectById(id);

        if (null != video) {
            video.setViews(video.getViews() + 1);

            videoMapper.updateById(video);
        }
    }

    @Override
    public String getViewCountType() {
        return ViewCountTypeEnum.VIDEO_VIEW.getType();
    }
}

6.3.活动类型

@Component
public class ActivityViewCountStrategy implements ViewCountStrategy {
    @Resource
    private SharedEStationsActivityMapper activityMapper;

    @Override
    public void increaseViewCount(Long id) {
        SharedEStationsActivity activity = activityMapper.selectById(id);
        if (activity != null) {
            activity.setViews(activity.getViews() + 1);

            activityMapper.updateById(activity);
        }
    }

    @Override
    public String getViewCountType() {
        return ViewCountTypeEnum.ACTIVITY_VIEW.getType();
    }
}

7. 最后定义了一个上下文类ViewCountContext 用来协调不同类型的浏览量递增的策略:

这个就是协调各业务类型的策略上下文。

// ViewCountContext.java

@Component
public class ViewCountContext {
    private final Map<String, ViewCountStrategy> strategies = new ConcurrentHashMap<>();

    @Autowired
    public ViewCountContext(List<ViewCountStrategy> strategyList) {
        strategyList.forEach(strategy -> strategies.put(strategy.getViewCountType(), strategy));
    }

    public void increaseViewCount(ViewCountIncreaseDto request) {
        ViewCountStrategy strategy = strategies.get(request.getViewCountType());
        if (strategy != null) {
            strategy.increaseViewCount(request.getId());
        }
    }
}

8. 实际使用

对于图片类型的浏览量递增

{
  "viewCountType": "pictureView",
  "id": 1
}

9.总结

通过使用策略模式,我们成功地将不同类型的浏览量递增操作进行了解耦,使得系统更加灵活和可维护。每个具体业务类都可以独立地进行扩展和修改,而不会影响到其他部分的代码。

以上就是一个简单的Spring Boot + 策略模式的实战示例。希望能帮到大家,欢迎大家多多交流。

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书语时

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值