范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

策略模式短信模板业务场景

  业务代码
  本文主要是介绍策略模式,重点就只在于短信发送时拒绝策略逻辑的处理,不相关的代码就不介绍了。
  主要的接口有两个 SmsTemplatePlaceHolderHandler 短信模板占位符处理器接口,SmsSendRejectStrategy短信发送拒绝策略接口,SmsTemplatePlaceHolderHandler有一个默认的实现类DefaultSmsTemplatePlaceHolderHandler,其关联了一个SmsSendRejectStrategy实例,在发送短信时,具体的短信发送拒绝策略实现类将进行具体的发送拒绝逻辑的处理,如果允许发送,则由DefaultSmsTemplatePlaceHolderHandler将替换了占位符的短信模板内容发出。
  其中,DefaultSmsTemplatePlaceHolderHandler与SmsSendRejectStrategy的关系就是一个具体的策略模式的体现,DefaultSmsTemplatePlaceHolderHandler无需关注拒绝发送的处理逻辑,调用SmsSendRejectStrategy实现类的实例进行处理即可。DefaultSmsTemplatePlaceHolderHandlerpackage com.cube.share.sms.handler;  import com.cube.share.base.utils.JacksonUtils; import com.cube.share.base.utils.PlaceHolderUtils; import com.cube.share.sms.constant.SmsConstant; import com.cube.share.sms.model.param.SmsPlaceHolderParameter; import com.cube.share.sms.strategy.SmsSendRejectStrategy; import com.cube.share.sms.strategy.SmsTemplateContext;  /**  * @author cube.li  * @date 2021/9/4 12:27  * @description 默认的短信模板占位符处理器  */ public class DefaultSmsTemplatePlaceHolderHandler implements SmsTemplatePlaceHolderHandler {      private SmsSendRejectStrategy rejectStrategy;      public DefaultSmsTemplatePlaceHolderHandler(SmsSendRejectStrategy rejectStrategy) {         this.rejectStrategy = rejectStrategy;     }      @Override     public String handle(SmsTemplateContext templateContext, SmsPlaceHolderParameter parameter) {         //发送拒绝策略         rejectStrategy.reject(templateContext, parameter);         return PlaceHolderUtils.replacePlaceHolder(templateContext.getTemplateContent(),                 JacksonUtils.toMap(parameter),                 SmsConstant.DEFAULT_PLACE_HOLDER_REGEX,                 SmsConstant.DEFAULT_PLACE_HOLDER_KEY_REGEX);     } }SmsSendRejectStrategypackage com.cube.share.sms.strategy;  import com.cube.share.base.utils.JacksonUtils; import com.cube.share.sms.model.param.SmsPlaceHolderParameter; import org.springframework.lang.NonNull;  import java.util.HashMap; import java.util.Map; import java.util.Set;  /**  * @author cube.li  * @date 2021/9/4 9:49  * @description 短信发送的拒绝策略  */ public interface SmsSendRejectStrategy {      /**      * 判断是否拒绝发送短信      *      * @param templateContext 短信模板上下文      * @param parameter       填充占位符的参数      */     void reject(SmsTemplateContext templateContext, SmsPlaceHolderParameter parameter);      /**      * 获取短信发送占位符替换参数Set(不包含value为null)      *      * @param parameter 填充占位符的参数      * @return Set      */     @NonNull     default Set getParameterSet(SmsPlaceHolderParameter parameter) {         Map parameterMap = getParameterMap(parameter);         return parameterMap.keySet();     }      /**      * 获取短信发送占位符替换参数Map(不包含value为null)      *      * @param parameter 填充占位符的参数      * @return Map      */     @NonNull     default Map getParameterMap(SmsPlaceHolderParameter parameter) {         Map parameterMap = JacksonUtils.toMap(parameter);         Map filteredParameterMap = new HashMap<>(4);         if (parameterMap != null) {             Set> entrySet = parameterMap.entrySet();             entrySet.forEach(stringObjectEntry -> {                 if (stringObjectEntry.getValue() != null) {                     filteredParameterMap.put(stringObjectEntry.getKey(), stringObjectEntry.getValue());                 }             });         }         return filteredParameterMap;     }  }
  三种拒绝策略的实现类package com.cube.share.sms.strategy;  import com.cube.share.sms.model.param.SmsPlaceHolderParameter;  /**  * @author cube.li  * @date 2021/9/4 11:54  * @description 短信发送拒绝策略-忽略策略,无论短信发送入参与模板是否匹配,都允许发送  */ public class SmsSendIgnoreStrategy implements SmsSendRejectStrategy {      @Override     public void reject(SmsTemplateContext templateContext, SmsPlaceHolderParameter parameter) {         //do nothing     } }package com.cube.share.sms.strategy;  import com.cube.share.base.templates.CustomException; import com.cube.share.sms.model.param.SmsPlaceHolderParameter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils;  import java.util.Set;  /**  * @author cube.li  * @date 2021/9/4 11:45  * @description SmsSendAnyMatchStrategy, 只要占位符参数匹配了短信模板中的任意一个占位符key,就允许发送  */ @Slf4j public class SmsSendAnyMatchStrategy implements SmsSendRejectStrategy {      @Override     public void reject(SmsTemplateContext templateContext, SmsPlaceHolderParameter parameter) {         Set parameterKeySet = getParameterSet(parameter);         if (CollectionUtils.intersection(templateContext.getPlaceHolderKeySet(), parameterKeySet).size() <= 0) {             log.error("短信占位符替换参数与短信模板完全不匹配,templateContent = {},parameter = {}", templateContext.getTemplateContent(), parameter);             throw new CustomException("短信占位符替换参数与短信模板完全不匹配");         }     } }package com.cube.share.sms.strategy;  import com.cube.share.base.templates.CustomException; import com.cube.share.sms.model.param.SmsPlaceHolderParameter; import lombok.extern.slf4j.Slf4j;  import java.util.Set;  /**  * @author cube.li  * @date 2021/9/4 11:57  * @description 短信发送拒绝策略-完全匹配,只有当短信入参与短信模板占位符完全匹配时才允许发送  */ @Slf4j public class SmsSendTotallyMatchStrategy implements SmsSendRejectStrategy {      @Override     public void reject(SmsTemplateContext templateContext, SmsPlaceHolderParameter parameter) {         Set parameterKeySet = getParameterSet(parameter);         if (!parameterKeySet.containsAll(templateContext.getPlaceHolderKeySet())) {             log.error("短信占位符替换参数与短信模板不完全匹配,templateContent = {},parameter = {}", templateContext.getTemplateContent(), parameter);             throw new CustomException("短信占位符替换参数与短信模板不完全匹配");         }     } }拒绝策略实例的创建工厂package com.cube.share.sms.factory;  import com.cube.share.sms.constant.SmsSendRejectStrategyEnum; import com.cube.share.sms.strategy.SmsSendAnyMatchStrategy; import com.cube.share.sms.strategy.SmsSendIgnoreStrategy; import com.cube.share.sms.strategy.SmsSendRejectStrategy; import com.cube.share.sms.strategy.SmsSendTotallyMatchStrategy;  /**  * @author cube.li  * @date 2021/9/4 12:49  * @description 拒绝策略工厂  */ public class SmsSendRejectStrategyFactory {      private static final SmsSendIgnoreStrategy IGNORE_STRATEGY = new SmsSendIgnoreStrategy();      private static final SmsSendAnyMatchStrategy ANY_MATCH_STRATEGY = new SmsSendAnyMatchStrategy();      private static final SmsSendTotallyMatchStrategy TOTALLY_MATCH_STRATEGY = new SmsSendTotallyMatchStrategy();      public static SmsSendRejectStrategy getStrategy(SmsSendRejectStrategyEnum strategyEnum) {         switch (strategyEnum) {             case IGNORE:                 return IGNORE_STRATEGY;             case ANY_MATCH:                 return ANY_MATCH_STRATEGY;             case TOTALLY_MATCH:                 return TOTALLY_MATCH_STRATEGY;             default:                 throw new IllegalArgumentException("Illegal StrategyEnum Param");         }     }  }短信发送服务package com.cube.share.sms.service;  import com.cube.share.base.templates.CustomException; import com.cube.share.sms.config.SmsConfig; import com.cube.share.sms.constant.SmsSendRejectStrategyEnum; import com.cube.share.sms.factory.SmsSendRejectStrategyFactory; import com.cube.share.sms.handler.DefaultSmsTemplatePlaceHolderHandler; import com.cube.share.sms.handler.SmsTemplatePlaceHolderHandler; import com.cube.share.sms.model.param.SmsSendParam; import com.cube.share.sms.strategy.SmsTemplateContext; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service;  import javax.annotation.Resource;  /**  * @author cube.li  * @date 2021/9/4 9:03  * @description 短信服务  */ @Service @Slf4j public class SmsService {      @Resource     private SmsConfig smsConfig;      private SmsTemplatePlaceHolderHandler placeHolderHandler =             new DefaultSmsTemplatePlaceHolderHandler(SmsSendRejectStrategyFactory.getStrategy(SmsSendRejectStrategyEnum.ANY_MATCH));      public void send(SmsSendParam param) {         String templateContent = smsConfig.getTemplates().get(param.getTemplateCode());         if (templateContent == null) {             throw new CustomException("不正确的短信模板");         }         SmsTemplateContext templateContext = SmsTemplateContext.from(templateContent, param.getTemplateCode());         String sendContent = placeHolderHandler.handle(templateContext, param.getParameter());         log.info("短信发送: {}", sendContent);     } }测试
  短信模板在配置文件中#短信 sms:   #模板   templates:     1: "尊敬的用户您好,{companyName}定于{address}开展主题为{title}的营销活动,活动时间{startTime}-{endTime},欢迎您的光临!"     2: "尊敬的用户您好,{address}开展主题为{title}的营销活动将于明天开始,欢迎您的光临!"
  单元测试类package com.cube.share.sms.service;  import com.cube.share.sms.model.param.SmsPlaceHolderParameter; import com.cube.share.sms.model.param.SmsSendParam; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;  import javax.annotation.Resource;  /**  * @author cube.li  * @date 2021/9/4 12:00  * @description  */ @SpringBootTest class SmsServiceTest {      @Resource     SmsService smsService;      @Test     void send() {         SmsSendParam smsSendParam = new SmsSendParam();         smsSendParam.setTemplateCode(1);         SmsPlaceHolderParameter placeHolderParameter = new SmsPlaceHolderParameter();         placeHolderParameter.setAddress("上海");         smsSendParam.setParameter(placeHolderParameter);         smsService.send(smsSendParam);     }  }
  更改拒绝策略,发送短信时日志如下:SmsSendAnyMatchStrategy2021-09-04 14:34:36.261  INFO 5528 --- [           main] com.cube.share.sms.service.SmsService    : 短信发送: 尊敬的用户您好,{companyName}定于上海开展主题为{title}的营销活动,活动时间{startTime}-{endTime},欢迎您的光临!
  可以看出,当拒绝策略为SmsSendAnyMatchStrategy时,只要占位符入参与短信模板中的占位符有一个匹配,就能够发送成功SmsSendTotallyMatchStrategy
  占位符参数与模板占位符不完全匹配时发送失败
  2021-09-04 14:38:16.133 ERROR 3896 --- [           main] c.c.s.s.s.SmsSendTotallyMatchStrategy    : 短信占位符替换参数与短信模板不完全匹配,templateContent = 尊敬的用户您好,{companyName}定于{address}开展主题为{title}的营销活动,活动时间{startTime}-{endTime},欢迎您的光临!,parameter = SmsPlaceHolderParameter(companyName=null, title=null, startTime=null, endTime=null, address=上海, url=null) com.cube.share.base.templates.CustomException: 短信占位符替换参数与短信模板不完全匹配      at com.cube.share.sms.strategy.SmsSendTotallyMatchStrategy.reject(SmsSendTotallyMatchStrategy.java:22)
  占位符参数与模板占位符完全匹配时发送成功
  完全匹配.png
  代码示例:https://gitee.com/li-cube/share/tree/master/sms总结
  业务逻辑说到底就是if-else,使用设计模式能够使代码更易维护、更易拓展,并且代码的阅读性更强;虽然不使用设计模式照样能够实现业务,不过就是多套几层if-else而已,但是人活着总归要有点追求,只有做到不止于业务、不止于代码,才能成为一个脱离低级CRUD的程序员。

16GB1T存储80万快充,上市一个月仍无现货,仅售5999元今年国内的手机市场厂商还是非常地少,在手机市场上的厂商在发展市场的时候也还是明里暗里都在较着劲,像此前小米12发布了之后,在手机市场上努比亚就紧随其后的发布了自己的骁龙8gen1处推荐一些过渡期用的显卡吧你们老嚷嚷着推荐显卡,那就推荐一期吧。但是呢,众所周知,现在显卡市场是个什么样子。所以,如果本期未达到你的预期也请见谅。那么不多说废话,下面进入正题吧。1入门中的入门,R5240这安卓旗舰都用上16G运存了,苹果却仍然停留在4G!不卡吗?从iPhone1到iPhone13,这么多年过去了,就连它的对手安卓都用上了16g的运存,可为什么苹果却仍然停留在4g运存呢?难道手机的运存不是越大越好吗?说到这,这里不得不提一下从1799元跌至1079元,4820mAh一亿像素四摄,售价更亲民了屏幕刷新率非常重要,可以让屏幕滑动显示更流畅,而用户们使用手机又经常需要和屏幕进行交互,所以让手机拥有高刷新率屏幕还是很有必要的,要知道就连手机行业风向标苹果公司都在iPhone1全球第一大芯片6400亿美金市值英伟达,发布144内核超级芯片H100全球第一大芯片企业6400亿美金市值的英伟达,22号晚上11点发布地球最强服务器芯片H100,英特尔和AMD作为服务器芯片巨头用瑟瑟发抖,都不足表达他们受到的冲击和压力,就相当于你网络安全开发商HUBCyberSecurity将借壳MountRainier(RNER。US)上市估值达12亿美元智通财经APP获悉,以色列网络安全解决方案开发商HUBCyberSecurity与特殊目的收购公司(SPAC)MountRainierAcquisitionCorp。(RNER。U无惧美国制裁!历时5年,中兴通讯观察期结束!新一轮5G浪潮将至每日中午12点更新市场午评晚间6点解读市场热点动动手,关注我,不迷路盘中直击大盘上午震荡调整,三大指数均小幅下跌。总体上个股跌多涨少,两市近3600只个股下跌。沪深两市半日成交额达杀入西欧,国产手机代表成功征服老外,外媒好评一片不知道大家有没有发现,华为的发布会总是在国外举行,你们知道为什么吗?简单来说就是重视国外市场,华为是要发展国际品牌。全球市场是华为重要收入来源,旗舰机型在欧洲发布有利于塑造全球品牌买对不买贵,实测RTX3050配什么CPU合适前言一说到DIY,多数人只会想到装机。其实DIY是一种行动,一种精神,并不局限于装机。真正的DIY玩家并不是要证明自己有多厉害,而是通过动手和选择实现花更少的钱获得更大的乐趣。同质一千多的手机和七八千的手机,有什么区别?真的是智商税吗现如今手机市场上,产品琳琅满目,面对市场上价格参差不齐的手机售价,很多朋友都有一个疑问,一千多的手机和七八千的手机有什么区别?多掏的钱真的是智商税吗?接下来就听妖妖给大家一个答案。怎样选择苹果手机苹果手机以出色的系统,流畅的运行速度受到用户的欢迎。苹果手机推荐哪款好?越贵得越好吗?大家之所以纠结,主要还是经济能力的限制,下面根据不同的价格范围,推荐几款苹果手机。一预算200
大学生最快的赚钱方式是什么?是学习不是挣快钱身为大学生,我们大部分的学生都是靠家里供养,经济独立的人占的是少数,为什么我们经济不独立,而别人就可以呢?这期我来和大家交流交流!一经济来源我们大部分的学子,经济来源于父母,我们都自学什么软件最赚钱,最合适自己软件只是一种工具,但是什么都不会,很难在社会上立足,也就难以赚到钱,所以要学习什么软件就至关重要了!一在校大学生需要学什么软件众所周知。大学生最不缺的是时间,所以说躺平还是锻炼自己即将步入大学的学子们,应该准备好如何丰富自己?提高自己的价值1。学习摄影知识不管是手机还是相机都可以。懂得都懂,要知道出门在外,不管是会拍照的男生还是女生都会是集体中的香饽饽,要是你技术好,还可以发展成副业做兼职,多一份收入。我记得自己现在个人创作的视频剪辑,如何进行账号定位账号定位第一步思考应该选择创作那方面的题材,如果个人面对摄像头的感觉良好,可以尝试个人vlog口播等等。如果是不喜欢出镜的,可以选择视频讲解搞笑段子励志演讲游戏解说等等。就励志解说学会了剪辑视频,怎么进行接单呢?如何进行变现呢?引言本期我来讲一下,视频剪辑如何进行变现,不管是学什么东西最大的目的就是进行实现价值,而剪辑视频最大的价值就是变现。我呢,从高中毕业就开始学习剪辑,并且和摄影摄像都是同期在做,到目2021宏碁全球秋季发布会诠释永续理念与科技完美融合要说目前全球的气候环境问题,确实是比较严峻,节能减排已经成了全球共识。而作为全球顶尖的资通讯公司之一,宏碁也尽到自己的一份力量。在2021年10月13日晚9点,以因你而生未你而来为中亦科技首发暂缓冷思百年老店靠什么?强者能量场弱者伤心地!作者于照野编辑李荷举风品邓亮蓝海来源铑财铑财研究院好事往往多磨。兜兜转转近9年,二战IPO的中亦科技冲关曙光就在眼前,其内部合理估计2021年11月前将完成首两会聚焦汽车行业代表们的建言科技,能源与全球化篇今天我们从自动驾驶,燃料电池和新能源汽车全球化角度,继续来聊有关两会汽车领域的代表和委员们的建言。自动驾驶加强政策法规支持,建立完善保险制度从2020年开始,各大车厂就开始启动面向改变自己是神,改变别人是蠢有一句话说的好你永远叫不醒一个装睡的人!不信任你的人,你即便掏出心来给他看,他也会说那是伪装不在乎你的人,你即便付出全部周全他,他也说你有所保留!对的人看你,怎么看怎么顺眼错的人看小小毛绒玩具,通过TikTok完成了两年500万美金的销售额SendAFriend,一个美国Shopify商家,通过TikTok在两年内实现了500万美元的销售额!这是SendAFriend的TikTok账号,他们主要拍摄内容是包装过程和客西城男孩20周年巡回演唱会采用BlackmagicDesign现场解决方案TheLEDShed公司在西城男孩20周年巡演英国和爱尔兰站的演出中,采用包含URSAMiniPro4。6K数字电影摄影机和ATEM4MEBroadcastStudio4K的现场制