日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

原来使用 Spring 实现策略模式可以这么简单!

發(fā)布時(shí)間:2025/3/16 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 原来使用 Spring 实现策略模式可以这么简单! 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

策略模式作為一種軟件設(shè)計(jì)模式,指對(duì)象有某個(gè)行為,但是在不同的場(chǎng)景中,該行為有不同的實(shí)現(xiàn)算法,可以替代代碼中大量的 if-else。

比如我們生活中的場(chǎng)景:買(mǎi)東西結(jié)賬可以使用微信支付、支付寶支付或者銀行卡支付,這些交易方式就是不同的策略。

那么在什么時(shí)候使用策略模式呢?

在《阿里巴巴Java開(kāi)發(fā)手冊(cè)》中有提到當(dāng)超過(guò) 3 層的 if-else 的邏輯判斷代碼可以使用策略模式來(lái)實(shí)現(xiàn)。

在 Spring 中實(shí)現(xiàn)策略模式的方式有很多種,下面通過(guò)一個(gè)案例來(lái)演示下,比如有個(gè)需求需要實(shí)現(xiàn)支持第三方登錄,目前需要支持以下三種登錄方式:

  • 微信登錄

  • QQ 登錄

  • 微博登錄

下面將通過(guò)策略模式來(lái)實(shí)現(xiàn)這個(gè)需求,其中策略模式結(jié)構(gòu)如下圖所示:

策略模式結(jié)構(gòu)如下圖所示:

策略模式結(jié)構(gòu)

主要包括一個(gè)登錄接口類(lèi)和幾種登錄方式的實(shí)現(xiàn)方式,并利用簡(jiǎn)單工廠來(lái)獲取對(duì)應(yīng)的處理器。

?

定義策略接口

首先定義一個(gè)登錄的策略接口 LoginHandler,其中包括兩個(gè)方法:

  • 獲取策略類(lèi)型的方法

  • 處理策略邏輯的方法

  • public?interface?LoginHandler<T?extends?Serializable>?{/***?獲取登錄類(lèi)型**?@return*/LoginType?getLoginType();/***?登錄**?@param?request*?@return*/LoginResponse<String,?T>?handleLogin(LoginRequest?request); }

    其中,LoginHandler 的 getLoginType 方法用來(lái)獲取登錄的類(lèi)型(即策略類(lèi)型),用于根據(jù)客戶(hù)端傳遞的參數(shù)直接獲取到對(duì)應(yīng)的策略實(shí)現(xiàn)。

    客戶(hù)端傳遞的相關(guān)參數(shù)都被封裝為 LoginRequest,傳遞給 handleLogin 進(jìn)行處理。

    @Data public?class?LoginRequest?{private?LoginType?loginType;private?Long?userId; }

    其中,根據(jù)需求定義登錄類(lèi)型枚舉如下:

    public?enum?LoginType?{QQ,WE_CHAT,WEI_BO; }

    ?

    ?

    實(shí)現(xiàn)策略接口

    在定義好策略接口后,我們就需要根據(jù)各種第三方登錄來(lái)實(shí)現(xiàn)對(duì)應(yīng)的處理邏輯就可以了。

    微信登錄

    @Component public?class?WeChatLoginHandler?implements?LoginHandler<String>?{private?final?Logger?logger?=?LoggerFactory.getLogger(this.getClass());/***?獲取登錄類(lèi)型**?@return*/@Overridepublic?LoginType?getLoginType()?{return?LoginType.WE_CHAT;}/***?登錄**?@param?request*?@return*/@Overridepublic?LoginResponse<String,?String>?handleLogin(LoginRequest?request)?{logger.info("微信登錄:userId:{}",?request.getUserId());String?weChatName?=?getWeChatName(request);return?LoginResponse.success("微信登錄成功",?weChatName);}private?String?getWeChatName(LoginRequest?request)?{return?"wupx";} }

    QQ 登錄

    @Component public?class?QQLoginHandler?implements?LoginHandler<Serializable>?{private?final?Logger?logger?=?LoggerFactory.getLogger(this.getClass());/***?獲取登錄類(lèi)型**?@return*/@Overridepublic?LoginType?getLoginType()?{return?LoginType.QQ;}/***?登錄**?@param?request*?@return*/@Overridepublic?LoginResponse<String,?Serializable>?handleLogin(LoginRequest?request)?{logger.info("QQ登錄:userId:{}",?request.getUserId());return?LoginResponse.success("QQ登錄成功",?null);} }

    微博登錄

    @Component public?class?WeiBoLoginHandler?implements?LoginHandler<Serializable>?{private?final?Logger?logger?=?LoggerFactory.getLogger(this.getClass());/***?獲取登錄類(lèi)型**?@return*/@Overridepublic?LoginType?getLoginType()?{return?LoginType.WEI_BO;}/***?登錄**?@param?request*?@return*/@Overridepublic?LoginResponse<String,?Serializable>?handleLogin(LoginRequest?request)?{logger.info("微博登錄:userId:{}",?request.getUserId());return?LoginResponse.success("微博登錄成功",?null);} }

    ?

    ?

    創(chuàng)建策略的簡(jiǎn)單工廠

    @Component public?class?LoginHandlerFactory?implements?InitializingBean,?ApplicationContextAware?{private?static?final?Map<LoginType,?LoginHandler<Serializable>>?LOGIN_HANDLER_MAP?=?new?EnumMap<>(LoginType.class);private?ApplicationContext?appContext;/***?根據(jù)登錄類(lèi)型獲取對(duì)應(yīng)的處理器**?@param?loginType?登錄類(lèi)型*?@return?登錄類(lèi)型對(duì)應(yīng)的處理器*/public?LoginHandler<Serializable>?getHandler(LoginType?loginType)?{return?LOGIN_HANDLER_MAP.get(loginType);}@Overridepublic?void?afterPropertiesSet()?throws?Exception?{//?將?Spring?容器中所有的?LoginHandler?注冊(cè)到?LOGIN_HANDLER_MAPappContext.getBeansOfType(LoginHandler.class).values().forEach(handler?->?LOGIN_HANDLER_MAP.put(handler.getLoginType(),?handler));}@Overridepublic?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{appContext?=?applicationContext;} }

    我們讓 LoginHandlerFactory實(shí)現(xiàn) InitializingBean 接口,在 afterPropertiesSet 方法中,基于 Spring 容器將所有 LoginHandler 自動(dòng)注冊(cè)到 LOGIN_HANDLER_MAP,從而 Spring 容器啟動(dòng)完成后, getHandler 方法可以直接通過(guò) loginType 來(lái)獲取對(duì)應(yīng)的登錄處理器。

    ?

    創(chuàng)建登錄服務(wù)

    在登錄服務(wù)中,我們通過(guò) LoginHandlerFactory 來(lái)獲取對(duì)應(yīng)的登錄處理器,從而處理不同類(lèi)型的第三方登錄:

    @Service public?class?LoginServiceImpl?implements?LoginService?{@Autowiredprivate?LoginHandlerFactory?loginHandlerFactory;@Overridepublic?LoginResponse<String,?Serializable>?login(LoginRequest?request)?{LoginType?loginType?=?request.getLoginType();//?根據(jù)?loginType?找到對(duì)應(yīng)的登錄處理器LoginHandler<Serializable>?loginHandler?=loginHandlerFactory.getHandler(loginType);//?處理登錄return?loginHandler.handleLogin(request);} }

    Factory 只負(fù)責(zé)獲取 Handler,Handler 只負(fù)責(zé)處理具體的登錄,Service 只負(fù)責(zé)邏輯編排,從而達(dá)到功能上的低耦合高內(nèi)聚。

    ?

    測(cè)試

    寫(xiě)一個(gè) Controller:

    @RestController public?class?LoginController?{@Autowiredprivate?LoginService?loginService;/***?登錄*/@PostMapping("/login")public?LoginResponse<String,?Serializable>?login(@RequestParam?LoginType?loginType,?@RequestParam?Long?userId)?{LoginRequest?loginRequest?=?new?LoginRequest();loginRequest.setLoginType(loginType);loginRequest.setUserId(userId);return?loginService.login(loginRequest);} }

    然后用 Postman 測(cè)下下:

    微信登錄QQ登錄

    是不是很簡(jiǎn)單呢?如果需求又要加需求,需要支持 GitHub 第三方登錄。

    此時(shí)我們只需要添加一個(gè)新的策略實(shí)現(xiàn),然后在登錄枚舉中加入對(duì)應(yīng)的類(lèi)型即可:

    @Component public?class?GitHubLoginHandler?implements?LoginHandler<Serializable>?{private?final?Logger?logger?=?LoggerFactory.getLogger(this.getClass());/***?獲取登錄類(lèi)型**?@return*/@Overridepublic?LoginType?getLoginType()?{return?LoginType.GIT_HUB;}/***?登錄**?@param?request*?@return*/@Overridepublic?LoginResponse<String,?Serializable>?handleLogin(LoginRequest?request)?{logger.info("GitHub登錄:userId:{}",?request.getUserId());return?LoginResponse.success("GitHub登錄成功",?null);} }

    此時(shí)不需要修改任何代碼 ,因?yàn)?Spring 容器重啟時(shí)會(huì)自動(dòng)將 GitHubLoginHandler 注冊(cè)到 LoginHandlerFactory 中,使用 Spring 實(shí)現(xiàn)策略模式就是這么簡(jiǎn)單,還不快學(xué)起來(lái)!

    有道無(wú)術(shù),術(shù)可成;有術(shù)無(wú)道,止于術(shù)

    歡迎大家關(guān)注Java之道公眾號(hào)

    好文章,我在看??

    總結(jié)

    以上是生活随笔為你收集整理的原来使用 Spring 实现策略模式可以这么简单!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亲切的金子餐桌片段的金子 | 色综合久久久久无码专区 | 色丁香av | 黄色国产片 | 亚洲狼人伊人 | 日本黄色美女 | 日日夜夜精品视频 | 国产呦小j女精品视频 | 青青青av | 日韩欧美一二三区 | 国产a免费 | 国产a级网站 | 亚洲成人动漫在线观看 | 亚洲av无码国产在丝袜线观看 | 日韩亚洲第一页 | 高清日韩一区二区 | 91免费在线| 久久99国产精品久久99果冻传媒 | 欧美日韩一区二区三区不卡视频 | 日韩精彩视频 | 欧美大尺度做爰啪啪床戏明星 | 久久久性 | 亚洲在线综合 | 夜夜嗨av色一区二区不卡 | 暴操白虎| 久久影院午夜 | av免费网站 | 人妻互换一二三区激情视频 | 欧美激情15p | 亚洲欧美日本一区二区三区 | 中国xxxx性xxxx产国 | 黑人玩弄人妻一区二区三区 | 福利毛片 | 国产夫妻在线观看 | 亚洲欧美综合 | 韩国三级与黑人 | 免费看女生隐私 | 日韩中文字幕在线观看视频 | 91大神精品在线 | 欧美日韩中文国产一区发布 | 国产麻豆剧传媒精品国产 | 美女交配 | 在线观看网站黄 | 国产精品theporn | 欧美国产中文 | 免费看黄色片视频 | 久久免费资源 | 免费在线视频观看 | 国产精品一区二区三区四区视频 | 亚洲精品xxx| 欧美自偷自拍 | 精品人妻伦一区二区三区久久 | 男人用嘴添女人下身免费视频 | 精品久久久久久久久久久久久久久久 | 国产精品成人久久久 | 欧美射射| 日本激情影院 | 亚洲精品入口 | 欧美jizzhd精品欧美18 | 日韩综合av | 国产九色在线播放九色 | 这里只有精品视频 | 青青青草视频 | 中文字幕一区二区三区电影 | 成年人免费在线视频 | 欧美男女交配 | 午夜国产小视频 | 午夜激情成人 | 中国av在线| 久久久久久久久蜜桃 | 精品一区在线观看视频 | 中文字幕一区二区三区视频 | 亚洲插| 久久肉| 超碰免费在线观看 | 木木影院 | 91久久人澡人人添人人爽欧美 | 免费精品在线视频 | 秋霞av网 | 国产欧美日本在线 | 欧美激情一区二区三区在线 | 久久理论电影 | 国产日韩成人 | 在线看毛片网站 | 潘金莲黄色一级片 | 亚洲h | 污片网站在线观看 | 免费高清视频一区二区三区 | 国产第113页 | 亚洲高清在线 | 好男人在线视频www 亚洲福利国产 | 精品动漫一区二区三区的观看方式 | 天天av天天翘 | 久久久久久中文字幕 | 影音先锋国产 | 日本色呦呦 | 免费看一级一片 | av中文字幕一区二区三区 | 亚洲深夜视频 |