当前位置: 首页 > news >正文

java设计模式之:策略模式+工厂模式整合案例实战(一)

本文介绍项目中常用的策略模式+工厂模式的案例,该案例是针对策略类比较少的情况下一篇会讲解策略类比较多的案例,下面直接开始:

案例1:项目中对系统中的客户和销售进行事件通知(短信、邮件、钉钉)

首先要有通知的策略接口,接口里面要有一个方法就是通知的方法

public interface PushChannelStrategy{// 通知方法SendResult send(MessagePushParam param,BaseMsg baseMsg);}

有了接口那必然有实现类,三个实现类短信、邮件、钉钉

短信:

@Slf4j
@Component
public class SmsPushChannelStrategy implements PushChannelStrategy{@Autowiredprivate NoticeClient noticeClient;@Overridepublic SendResult send(MessagePushParam param,BaseMsg baseMsg){//1、before send check//2、send smsNoticeResult noticeResult=noticeClient.sendSms(xxxx);sendResult.setMessageStatus(MessageStatusEnum.SUCCESS);return sendResult;}
}

邮件:

@Slf4j
@Component
public class EmailPushChannelStrategy implements PushChannelStrategy{@Autowiredprivate NoticeClient noticeClient;@Overridepublic SendResult send(MessagePushParam param,BaseMsg baseMsg){//1、before send check//2、send emailEmail emailMsg=(Email)baseMsg;NoticeResult noticeResult=noticeClient.sendEmail(xxxx);sendResult.setMessageStatus(MessageStatusEnum.SUCCESS);return sendResult;}
}

钉钉:

@Slf4j
@Component
public class DingTalkPushChannelStrategy implements PushChannelStrategy{@Autowiredprivate DingTalkClient dingTalkClient;@Overridepublic SendResult send(MessagePushParam param,BaseMsg baseMsg){//1、before send check//2、send ding talkSendResult sendResult=dingTalkClient.send(xxx);// 其他结果参数组装return sendResult;}
}

然后通过策略工厂来获取具体的策略类:(由于只有三个策略类,所以通过注入的方式对channel进行判断)

@Component
public class PushChannelStrategyFactory{@Autowired private DingTalkPushChannelStrategy dingTalkPushChannelStrategy;@Autowiredprivate SmsPushChannelStrategy smsPushChannelStrategy;@Autowiredprivate EmailPushChannelStrategy emailPushChannelStrategy;public PushChannelStrategy getStrategy(PushChannel pushChannel){switch(pushChannel){case DING_TALK:return dingTalkPushChannelStrategy;case SMS:return smsPushChannelStrategy;case EMAIL:return emailPushChannelStrategy;default:throw new RuntimeException("不支持的类型");}}
}

当然策略工厂针对策略实现类比较少的情况还可以这样写:

@Component
public class PushChannelStrategyFactory2{@Autowiredprivate DingTalkPushChannelStrategy dingTalkPushChannelStrategy;@Autowiredprivate SmsPushChannelStrategy smsPushChannelStrategy;@Autowiredprivate EmailPushChannelStrategy emailPushChannelStrategy;private static final Map<PushChannel,PushChannelStrategy> pushChannelBuilderMap=new HashMap<>();@PostConstructpublic void init(){pushChannelBuilderMap.put(PushChannel.SMS,smsPushChannelStrategy);pushChannelBuilderMap.put(PushChannel.Email,emailPushChannelStrategy);pushChannelBuilderMap.put(PushChannel.DING_TALK,dingTalkPushChannelStrategy);}Public PushChannelStrategy getStrategy(PushChannel PushChannel){if(PushChannel==null){return null;}return pushChannelBuilderMap.get(PushChannel);}
}

用到的枚举类:

@Getter
public enum PushChannel{SMS("sms","短信"),EMAIL("email","邮件"),DING_TALK("dingTalk","钉钉");private final String value;PushChannel(String value,String desc){this.value=value;}public static PushChannel getPushChannel(String pushChannel){if(pushChannel==null){return null;}for(PushChannel channel:PushChannel.values()){if(pushChannel.equals(channel.getValue())){return channel;}}return null;}
}

在使用的时候通过策略工厂里面的方法获取具体的策略类:

@Slf4j
@Servicepublic class MessagePushService{@Autowiredprivate PushChannelStrategyFactory pushChannelStrategyFactory;@Autowiredprivate MessageRecordRepository messageRecordRepository;public ResultDTO<Boolean> pushSync(MessagePushCommand command){MessagePushParam messagePushParam =MessagePushAssembler.convert(command);//1,业务逻辑处理//2、根据渠道进行触达PushChannel pushChannel=messagePushParam.getChannel();if(pushChannel==null){throw new MessagePushException(xxx);}//3、获取具体的策略类PushChannelStrategy pushChannelStrategy=pushChannelStrategyFactory.getStrategy(pushChannel);SendResult sendResult=PushChannelStrategy.send(messagePushParam,xxx);//4,记录落库return ResultDTO.getSuccessResult(true);}}

到此该版本的策略模式+工厂模式就结束了,欢迎点评和指出不足之处。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【C++深入学习】类和对象(一)
  • QT5.12.9 通过MinGW64 / MinGW32 cmake编译Opencv4.5.1
  • [笔试题] 笔试题面试题
  • 218.贪心算法:分发糖果(力扣)
  • python如何与前端交互
  • Qt之元对象系统
  • 计算机课程名,汇总
  • Windows系统网络配置命令详细指南
  • 编程题目积累(day5)
  • CSS技巧专栏:一日一例 2.纯CSS实现 多彩边框按钮特效
  • 296个地级市GDP相关数据(2000-2023年)
  • 右键连点器
  • 支持向量机 (support vector machine,SVM)
  • UML建模案例分析-类图中的关系
  • 大模型/NLP/算法面试题总结2——transformer流程//多头//clip//对比学习//对比学习损失函数
  • Angular 响应式表单 基础例子
  • co.js - 让异步代码同步化
  • docker-consul
  • eclipse的离线汉化
  • Hexo+码云+git快速搭建免费的静态Blog
  • Iterator 和 for...of 循环
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • php的插入排序,通过双层for循环
  • PHP面试之三:MySQL数据库
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • Zepto.js源码学习之二
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 浮动相关
  • 技术胖1-4季视频复习— (看视频笔记)
  • 码农张的Bug人生 - 初来乍到
  • 异常机制详解
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 最近的计划
  • 仓管云——企业云erp功能有哪些?
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 如何正确理解,内页权重高于首页?
  • !!Dom4j 学习笔记
  • #android不同版本废弃api,新api。
  • #if #elif #endif
  • $().each和$.each的区别
  • $(selector).each()和$.each()的区别
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (day18) leetcode 204.计数质数
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (算法二)滑动窗口
  • (未解决)macOS matplotlib 中文是方框
  • (转)重识new
  • (轉貼) UML中文FAQ (OO) (UML)
  • **python多态