日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Spring 環(huán)境下實(shí)現(xiàn)策略模式的示例

瀏覽:162日期:2023-08-09 10:10:15

背景

最近在忙一個(gè)需求,大致就是給滿足特定條件的用戶發(fā)營(yíng)銷郵件,但是用戶的來(lái)源有很多方式:從 ES 查詢的、從 csv 導(dǎo)入的、從 MongoDB 查詢….. 需求很簡(jiǎn)單,但是怎么寫的優(yōu)雅,方便后續(xù)擴(kuò)展,就存在很多門道了。

我們的項(xiàng)目是基于 Spring Boot 開(kāi)發(fā)的,因此這篇文章也會(huì)基于 Spring Boot 作為基礎(chǔ)框架,教你如何使用 Spring 依賴注入的特性,優(yōu)雅的實(shí)現(xiàn)策略模式。

1. 簡(jiǎn)單粗暴

最簡(jiǎn)單粗暴直接的方式莫過(guò)于 if...else… 了,偽代碼如下:

if(來(lái)源 == ES){ // TODO: ES Query}else if(來(lái)源 == CSV){ // TODO: Read CSV File}else if(來(lái)源 == MongoDB){ // TODO: MongoDB Query}

如果后面還需要從其他平臺(tái)獲取,那就在接著添加 else if...,這種方式固然簡(jiǎn)單直接,但是當(dāng)后續(xù)擴(kuò)展的方式越來(lái)越多,相應(yīng)的if...else...也會(huì)越來(lái)越長(zhǎng),emmm….. 怎么說(shuō)呢,黑貓白貓,能抓到老鼠的就是好貓。

2. 策略模式

在 Spring 環(huán)境下實(shí)現(xiàn)策略模式異常簡(jiǎn)單,畢竟 Spring 提供的依賴注入簡(jiǎn)直就是開(kāi)發(fā)利器~

既然是策略模式,那么定義策略肯定是首當(dāng)其沖,策略我們使用枚舉實(shí)現(xiàn)最佳。

public enum GroupType { /** * 從 ES 查詢 */ ES, /** * 從 MongoDB 查詢 */ MONGODB, /** * 從 文件 讀取 */ FILE}

下一步,我們定義一個(gè)接口,用于抽象通用的功能。

public interface IGroupSelect { /** * 人群獲取方式 * * @return 人群選擇枚舉 */ GroupType type(); /** * 查詢滿足條件的用戶 * * @param groupQuery 查詢條件 * @return 滿足條件的用戶 */ default List<GroupUser> queryUser(GroupQuery groupQuery) { checkQueryCondition(groupQuery); return doQuery(groupQuery); } /** * 事前校驗(yàn)查詢條件 * * @param groupQuery 查詢條件 * @throws IllegalArgumentException 參數(shù)異常 */ void checkQueryCondition(GroupQuery groupQuery) throws IllegalArgumentException; /** * 真正的查詢方法 * * @param groupQuery 查詢條件 * @return 滿足條件的用戶 */ List<GroupUser> doQuery(GroupQuery groupQuery);}

這一步,小伙伴們有沒(méi)有發(fā)現(xiàn)里面也包含了模板方法模式呢?

然后就是不同策略的具體實(shí)現(xiàn)了。

ES 策略

@Slf4j@Servicepublic class EsGroupSelect implements IGroupSelect { /** * 人群獲取方式 * * @return 人群選擇枚舉 */ @Override public GroupType type() { return GroupType.ES; } /** * 事前校驗(yàn)查詢條件 * * @param groupQuery 查詢條件 * @throws IllegalArgumentException 參數(shù)異常 */ @Override public void checkQueryCondition(GroupQuery groupQuery) throws IllegalArgumentException { log.info('groupQuery = {}', groupQuery); } /** * 查詢滿足條件的用戶 * * @param groupQuery 查詢條件 * @return 滿足條件的用戶 */ @Override public List<GroupUser> doQuery(GroupQuery groupQuery) { List<GroupUser> result = new ArrayList<>(); // TODO: // 1. 復(fù)雜的 ES 查詢邏輯 // 2. 根據(jù)條件篩選滿足條件的用戶數(shù)據(jù) for (int i = 1; i <= 15; i++) { result.add(GroupUser.of('ES用戶' + i, i + '@es.com')); } return result; }} 文件策略

@Slf4j@Servicepublic class FileGroupSelect implements IGroupSelect { /** * 人群獲取方式 * * @return 人群選擇枚舉 */ @Override public GroupType type() { return GroupType.FILE; } /** * 事前校驗(yàn)查詢條件 * * @param groupQuery 查詢條件 * @throws IllegalArgumentException 參數(shù)異常 */ @Override public void checkQueryCondition(GroupQuery groupQuery) throws IllegalArgumentException { log.info('groupQuery = {}', groupQuery); } /** * 查詢滿足條件的用戶 * * @param groupQuery 查詢條件 * @return 滿足條件的用戶 */ @Override public List<GroupUser> doQuery(GroupQuery groupQuery) { List<GroupUser> result = new ArrayList<>(); // TODO: // 1. 復(fù)雜的解析、讀文件 // 2. 根據(jù)條件篩選滿足條件的用戶數(shù)據(jù) for (int i = 1; i <= 3; i++) { result.add(GroupUser.of('文件讀取用戶' + i, i + '@file.com')); } return result; }} MongoDB 策略

@Slf4j@Servicepublic class MongoGroupSelect implements IGroupSelect { /** * 人群獲取方式 * * @return 人群選擇枚舉 */ @Override public GroupType type() { return GroupType.MONGODB; } /** * 事前校驗(yàn)查詢條件 * * @param groupQuery 查詢條件 * @throws IllegalArgumentException 參數(shù)異常 */ @Override public void checkQueryCondition(GroupQuery groupQuery) throws IllegalArgumentException { log.info('groupQuery = {}', groupQuery); } /** * 查詢滿足條件的用戶 * * @param groupQuery 查詢條件 * @return 滿足條件的用戶 */ @Override public List<GroupUser> doQuery(GroupQuery groupQuery) { List<GroupUser> result = new ArrayList<>(); // TODO: // 1. 復(fù)雜的 MongoDB 查詢邏輯 // 2. 根據(jù)條件篩選滿足條件的用戶數(shù)據(jù) for (int i = 1; i <= 7; i++) { result.add(GroupUser.of('MongoDB用戶' + i, i + '@mongo.com')); } return result; }}

現(xiàn)在到了最后一步,就是如何通過(guò) Spring 優(yōu)雅的實(shí)現(xiàn)策略模式的選擇呢?敲黑板,考試必考!

我們通過(guò)定義一個(gè)工廠類,然后使用 Spring 的依賴注入特性,可以注入一個(gè)接口的多個(gè)實(shí)現(xiàn),這里采用 List<IGroupSelect> 的形式注入,Spring 也支持通過(guò) Map<String,IGroupSelect> 的形式注入,如果使用 Map 注入,那么 key 就是類名,小伙伴們自己也可以測(cè)試一下~

@Servicepublic class GroupSelectFactory { @Autowired private List<IGroupSelect> groupSelectList; /** * 根據(jù)人群類型選擇具體的實(shí)現(xiàn)類 * * @param type 人群類型 * @return 人群選擇具體實(shí)現(xiàn)類 */ public IGroupSelect getGroupSelect(GroupType type) { Optional<IGroupSelect> groupSelectOptional = groupSelectList.stream().filter(t -> t.type() == type).findAny(); return groupSelectOptional.orElseThrow(() -> new IllegalArgumentException('暫不支持該人群方式')); }}

最后寫個(gè)定時(shí)任務(wù)測(cè)試一下吧。

@Autowiredprivate GroupSelectFactory groupSelectFactory;/** * 模擬定時(shí)發(fā)送營(yíng)銷郵件 */@Scheduled(cron = '0/10 * * * * ?')public void sendEmailTask() { List<SendEmailTask> taskList = new ArrayList<>(); for (GroupType groupType : GroupType.values()) { GroupQuery groupQuery = new GroupQuery('虛頭巴腦的 ' + groupType.name() + ' 查詢條件'); taskList.add(SendEmailTask.of(groupType, groupQuery)); } taskList.forEach(task -> { List<GroupUser> groupUsers = groupSelectFactory.getGroupSelect(task.getType()).queryUser(task.getQuery()); log.info('groupUsers = {}', groupUsers); });}@Data@NoArgsConstructor@AllArgsConstructor(staticName = 'of')static class SendEmailTask implements Serializable { private static final long serialVersionUID = -3461263089669779193L; private GroupType type; private GroupQuery query;}

觀察控制臺(tái),看看日志輸出吧~

總結(jié)

本文使用策略模式實(shí)現(xiàn)不同人群的查詢,后續(xù)如果要增加短信、微信、釘釘?shù)南l(fā)送,是不是也可以用策略模式實(shí)現(xiàn)呢? 使用 Spring 的依賴注入特性,可以注入一個(gè)接口的多個(gè)實(shí)現(xiàn),很容易就實(shí)現(xiàn)了策略模式的選擇,這樣后續(xù)添加一種策略的時(shí)候,完全不需要改動(dòng)主要邏輯,只需添加具體實(shí)現(xiàn)即可。 細(xì)心的小伙伴可以發(fā)現(xiàn),本文雖然是講策略模式,其實(shí)里面還包含了模板方法、工廠模式,多種設(shè)計(jì)模式的協(xié)同作戰(zhàn),食用味道更佳喲~

配套代碼:https://github.com/xkcoding/practice_demo/tree/master/strategy-design-pattern-in-spring

以上就是Spring 環(huán)境下實(shí)現(xiàn)策略模式的示例的詳細(xì)內(nèi)容,更多關(guān)于Spring 實(shí)現(xiàn)策略模式的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
高清av不卡| 精品视频自拍| 亚洲精品裸体| 亚洲精品在线观看91| 精品视频在线观看网站| 国产极品久久久久久久久波多结野| 91亚洲无吗| 男人操女人的视频在线观看欧美| 国产一区亚洲| 日本激情一区| 国产在线不卡一区二区三区 | 久久久夜精品| 精品一区91| 欧美成a人免费观看久久| 色在线视频观看| 精品免费av| 国产综合色区在线观看| 国产理论在线| 99久久激情| 国产偷自视频区视频一区二区| 99精品视频精品精品视频| 国产精品久久久久久妇女| 欧美一级全黄| 国产欧美一区二区三区国产幕精品 | 日韩av黄色在线| 国产精品一区毛片| 国产精品久久久久av蜜臀| 国产精品xxx在线观看| 国产精品99久久免费观看| 久久精品国产99国产| 久久一区欧美| 欧美日韩中文字幕一区二区三区| 麻豆9191精品国产| 婷婷精品在线观看| 亚洲ww精品| 美女性感视频久久| 久久一区二区三区电影| 99国产精品久久久久久久| 日韩中文字幕亚洲一区二区va在线| 亚洲婷婷丁香| 国产欧美一区二区精品久久久 | 99热精品久久| 蜜臀av国产精品久久久久| 欧美精品国产| 国产精品日本一区二区三区在线| 麻豆91在线播放| 国产成人精品亚洲线观看| 成人在线免费观看91| 国产精品99免费看| 一区二区三区四区日韩| 成人午夜在线| 欧洲激情综合| 久久狠狠亚洲综合| 亚洲天堂久久| 91欧美日韩在线| 激情视频网站在线播放色| 日韩高清欧美激情| 久久精品123| 婷婷亚洲精品| 激情欧美一区二区三区| 亚洲精品乱码久久久久久蜜桃麻豆 | 激情国产在线| 另类av一区二区| 欧美专区一区| 日韩不卡免费高清视频| 日韩三级一区| 日本在线啊啊| 国产日韩一区二区三免费高清| 四虎影视精品| 涩涩涩久久久成人精品| 亚洲女同一区| 日韩精品91| 中文字幕中文字幕精品| 99精品视频精品精品视频| 国产乱论精品| 精品亚洲成人| 中文字幕成人| 国产麻豆久久| 久久精品一区| 日韩中文字幕麻豆| 国产一区二区三区视频在线| 亚洲三级视频| 亚洲午夜电影| 亚洲成a人片| 激情中国色综合| 国产日韩欧美一区在线| 先锋亚洲精品| 日韩欧美二区| 国产精品99视频| 青草av.久久免费一区| 久久久精品五月天| 国产精品久久观看| 国产精品免费大片| 亚洲ab电影| 日韩一区二区三区免费视频| 亚洲国内精品| 久久久天天操| 免费欧美一区| 日本综合字幕| 亚洲va在线| 欧美日韩免费观看视频| 国产精品99在线观看| av最新在线| 国产一区二区三区四区大秀| 欧美1区二区| 国产一区 二区| 日本大胆欧美人术艺术动态| 樱桃成人精品视频在线播放| 91久久久精品国产| 久久久五月天| 国产婷婷精品| 国产亚洲毛片| 蜜臀av国产精品久久久久| 亚洲精品护士| 乱人伦精品视频在线观看| 国产精品呻吟| 亚洲aⅴ网站| 在线国产精品一区| 日本va欧美va欧美va精品| 日本成人手机在线| 婷婷六月综合| 久久香蕉精品| 免费看黄色91| 国产三级一区| 美女视频网站久久| 福利精品在线| 亚洲成人三区| 免费人成黄页网站在线一区二区| 日韩高清成人在线| 日本视频在线一区| 国产欧美丝祙| 精品久久99| 久久丁香四色| 国产精品黄色片| 国产精品亚洲欧美| 日韩av电影一区| 日韩超碰人人爽人人做人人添| 亚洲精品自拍| 国产精品视频一区二区三区| 国产福利亚洲| 天堂√中文最新版在线| 激情综合自拍| 国产精品一区二区三区美女 | 国产精品xx| 久久精品1区| 久久精品99久久无色码中文字幕| 久久香蕉国产| 免费人成在线不卡| 国产精品视频一区视频二区| 播放一区二区| 亚洲女人av| 欧美日本久久| 秋霞影视一区二区三区| 日本va欧美va欧美va精品| 欧美激情91| 激情丁香综合| 国产福利资源一区| 91精品国产调教在线观看| 波多视频一区| 欧美日韩亚洲一区二区三区在线 | 免费观看不卡av| 97久久中文字幕| 国产videos久久| 中文不卡在线| 五月天av在线| 美美哒免费高清在线观看视频一区二区| 日韩高清电影免费| 日韩在线观看一区| 亚洲18在线| 国产理论在线| 丝袜亚洲精品中文字幕一区| 国产免费播放一区二区| 久久一级电影| 久久国产精品免费一区二区三区| 不卡专区在线| 日本美女一区| 一区二区三区网站| 日韩**一区毛片| 日韩免费视频| 日韩成人午夜精品| 久久久777| 91大神在线观看线路一区| 亚洲精品.com| 日韩一区免费| 亚洲天堂黄色| 国产午夜精品一区在线观看| 好吊一区二区三区| 精品三级av| 国内精品福利| 国产精品久久久久av蜜臀| 蜜乳av另类精品一区二区| 国产高潮在线| 日韩一区二区三区四区五区| 999久久久国产精品| 高清久久一区| 久久国际精品| 免费日韩一区二区| 国产99精品一区| 国产成人免费视频网站视频社区| 亚洲资源在线|