在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

為什么我不再推薦枚舉策略模式?

jf_ro2CN3Fa ? 來源:芋道源碼 ? 2023-04-14 10:52 ? 次閱讀


一、為什么講策略模式

策略模式,應該是工作中比較常用的設計模式,調用方自己選擇用哪一種策略完成對數據的操作,也就是“一個類的行為或其算法可以在運行時更改”

我個人的理解是 將一些除了過程不同其他都一樣的函數封裝成策略,然后調用方自己去選擇想讓數據執行什么過程策略。常見的例子為根據用戶分類推薦不同的排行榜(用戶關注點不一樣,推薦榜單就不一樣)

和單例模式一樣,隨著時間發展,我不再推薦經典策略模式,更推薦簡單策略用枚舉策略模式,復雜地用工廠策略模式。下面引入一個例子,我們的需求是:對一份股票數據列表,給出低價榜、高價榜、漲幅榜。這其中只有排序條件的區別,比較適合作為策略模式的例子

基于 Spring Boot + MyBatis Plus + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

二、經典策略模式

數據DTO

@Data
publicclassStock{

//股票交易代碼
privateStringcode;

//現價
privateDoubleprice;

//漲幅
privateDoublerise;
}

抽象得到的策略接口

publicinterfaceStrategy{

/**
*將股票列表排序
*
*@paramsource源數據
*@return排序后的榜單
*/
Listsort(Listsource);
}

實現我們的策略類

/**
*高價榜
*/
publicclassHighPriceRankimplementsStrategy{

@Override
publicListsort(Listsource){
returnsource.stream()
.sorted(Comparator.comparing(Stock::getPrice).reversed())
.collect(Collectors.toList());
}
}

/**
*低價榜
*/
publicclassLowPriceRankimplementsStrategy{

@Override
publicListsort(Listsource){
returnsource.stream()
.sorted(Comparator.comparing(Stock::getPrice))
.collect(Collectors.toList());
}
}

/**
*高漲幅榜
*/
publicclassHighRiseRankimplementsStrategy{

@Override
publicListsort(Listsource){
returnsource.stream()
.sorted(Comparator.comparing(Stock::getRise).reversed())
.collect(Collectors.toList());
}
}

經典的Context類,

publicclassContext{
privateStrategystrategy;

publicvoidsetStrategy(Strategystrategy){
this.strategy=strategy;
}

publicListgetRank(Listsource){
returnstrategy.sort(source);
}
}

于是 我們順禮成章地得到調用類--榜單實例RankServiceImpl

@Service
publicclassRankServiceImpl{

/**
*dataService.getSource()提供原始的股票數據
*/
@Resource
privateDataServicedataService;

/**
*前端傳入榜單類型,返回排序完的榜單
*
*@paramrankType榜單類型
*@return榜單數據
*/
publicListgetRank(StringrankType){
//創建上下文
Contextcontext=newContext();
//這里選擇策略
switch(rankType){
case"HighPrice":
context.setStrategy(newHighPriceRank());
break;
case"LowPrice":
context.setStrategy(newLowPriceRank());
break;
case"HighRise":
context.setStrategy(newHighRiseRank());
break;
default:
thrownewIllegalArgumentException("rankTypenotfound");
}
//然后執行策略
returncontext.getRank(dataService.getSource());
}
}

我們可以看到經典方法,創建了一個接口、三個策略類,還是比較啰嗦的。調用類的實現也待商榷,新增一個策略類還要修改榜單實例(可以用抽象工廠解決,但是復雜度又上升了)。加之我們有更好的選擇,所以此處不再推薦經典策略模式

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

三、基于枚舉的策略模式

這里對這種簡單的策略,推薦用枚舉進行優化。枚舉的本質是創建了一些靜態類的集合。

我下面直接給出例子,大家可以直觀感受一下

枚舉策略類

publicenumRankEnum{
//以下三個為策略實例
HighPrice{
@Override
publicListsort(Listsource){
returnsource.stream()
.sorted(Comparator.comparing(Stock::getPrice).reversed())
.collect(Collectors.toList());
}
},
LowPrice{
@Override
publicListsort(Listsource){
returnsource.stream()
.sorted(Comparator.comparing(Stock::getPrice))
.collect(Collectors.toList());
}
},
HighRise{
@Override
publicListsort(Listsource){
returnsource.stream()
.sorted(Comparator.comparing(Stock::getRise).reversed())
.collect(Collectors.toList());
}
};

//這里定義了策略接口
publicabstractListsort(Listsource);
}

對應的調用類也得以優化,榜單實例RankServiceImpl

@Service
publicclassRankServiceImpl{

/**
*dataService.getSource()提供原始的股票數據
*/
@Resource
privateDataServicedataService;

/**
*前端傳入榜單類型,返回排序完的榜單
*
*@paramrankType榜單類型形似RankEnum.HighPrice.name()
*@return榜單數據
*/
publicListgetRank(StringrankType){
//獲取策略,這里如果未匹配會拋IllegalArgumentException異常
RankEnumrank=RankEnum.valueOf(rankType);
//然后執行策略
returnrank.sort(dataService.getSource());
}
}

可以看到,如果策略簡單的話,基于枚舉的策略模式優雅許多,調用方也做到了0修改,但正確地使用枚舉策略模式需要額外考慮以下幾點。

  • 枚舉的策略類是公用且靜態,這意味著這個策略過程不能引入非靜態的部分,擴展性受限
  • 策略模式的目標之一,是優秀的擴展性和可維護性,最好能新增或修改某一策略類時,對其他類是無改動的。而枚舉策略如果過多或者過程復雜,維護是比較困難的,可維護性受限

四、基于工廠的策略模式

為了解決良好的擴展性和可維護性,我更推薦以下利用spring自帶beanFactory的優勢,實現一個基于工廠的策略模式。

策略類改動只是添加了@Service注解,并指定了Service的value屬性

/**
*高價榜
*注意申明Service.value=HighPrice,他是我們的key,下同
*/
@Service("HighPrice")
publicclassHighPriceRankimplementsStrategy{

@Override
publicListsort(Listsource){
returnsource.stream()
.sorted(Comparator.comparing(Stock::getPrice).reversed())
.collect(Collectors.toList());
}
}

/**
*低價榜
*/
@Service("LowPrice")
publicclassLowPriceRankimplementsStrategy{

@Override
publicListsort(Listsource){
returnsource.stream()
.sorted(Comparator.comparing(Stock::getPrice))
.collect(Collectors.toList());
}
}

/**
*高漲幅榜
*/
@Service("HighRise")
publicclassHighRiseRankimplementsStrategy{

@Override
publicListsort(Listsource){
returnsource.stream()
.sorted(Comparator.comparing(Stock::getRise).reversed())
.collect(Collectors.toList());
}
}

調用類修改較大,接入借助spring工廠特性,完成策略類

@Service
publicclassRankServiceImpl{

/**
*dataService.getSource()提供原始的股票數據
*/
@Resource
privateDataServicedataService;
/**
*利用注解@Resource@Autowired特性,直接獲取所有策略類
*key=@Service的value
*/
@Resource
privateMaprankMap;

/**
*前端傳入榜單類型,返回排序完的榜單
*
*@paramrankType榜單類型和Service注解的value屬性一致
*@return榜單數據
*/
publicListgetRank(StringrankType){
//判斷策略是否存在
if(!rankMap.containsKey(rankType)){
thrownewIllegalArgumentException("rankTypenotfound");
}
//獲得策略實例
Strategyrank=rankMap.get(rankType);
//執行策略
returnrank.sort(dataService.getSource());
}
}

若讀者使用的不是Spring,也可以找找對應框架的工廠模式實現,或者自己實現一個抽象工廠。

工廠策略模式會比枚舉策略模式啰嗦,但也更加靈活、易擴展性和易維護。故簡單策略推薦枚舉策略模式,復雜策略才推薦工廠策略模式。



審核編輯 :李倩



聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 框架
    +關注

    關注

    0

    文章

    404

    瀏覽量

    17733
  • 函數
    +關注

    關注

    3

    文章

    4365

    瀏覽量

    63830

原文標題:為什么我不再推薦枚舉策略模式?

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    電機大范圍調速的綜合電壓調制策略

    針對電動汽車要求驅動電機具有大范圍調速要求和目前任何單種基本調制方式都無法做到全調制比范圍內性能最優的問題,提出了一種綜合的調制策略:在低調制比階段使用傳統的SVPWM策略,在高調制比階段
    發表于 04-01 14:51

    永磁同步電機矢量控制策略分析

    本文通過矢量控制策略采用 id=0 控制方案快速準確地控制轉矩,實現調速系統具有較高的動態性能。并利用了 Matlab 工具對永磁同步電機矢量控制系統在空載起動、轉速突變、負載突變進行了仿真研究。 點擊附件可直接打開查看全文*附件:永磁同步電機矢量控制策略分析.docx
    發表于 03-20 12:57

    淵亭KGAG升級引入“高級策略推理”

    為了突破現有AI技術在決策推理方面的局限,淵亭科技對其知識圖譜分析平臺KGAG進行了最新升級,創新性地引入了“高級策略推理”模式。這一模式的引入,實現了“大模型×知識圖譜×專家策略×動
    的頭像 發表于 02-14 15:07 ?400次閱讀

    設計模式-策略模式

    作者:京東工業 孫磊 一、概念 策略模式(Strategy Pattern)也稱為(Policy Parttern)。 它定義了算法家族,分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變換
    的頭像 發表于 01-08 13:47 ?257次閱讀
    設計<b class='flag-5'>模式</b>-<b class='flag-5'>策略</b><b class='flag-5'>模式</b>

    Java 枚舉策略模式、函數式接口的結合:實現高內聚低耦合的設計

    中,通常會使用枚舉來定義業務上的一組常量,那除了簡單地定義常量之外,我們如何利用枚舉來實現高內聚、低耦合的設計呢?下面介紹下枚舉策略模式
    的頭像 發表于 11-21 14:06 ?490次閱讀

    請問什么情況下會損壞TLV2548,或者導致INT信號不再反應?

    如題,請問什么情況下會損壞TLV2548,或者導致INT信號不再反應? 曾多次驅動過該AD,都可以正常讀取碼值。但有兩次遇到過AD沒有任何反應,只在上電的瞬間讀取電壓,INT不再拉低(
    發表于 11-14 06:39

    蘋果調整策略:逐步摒棄年更產品發布模式

    10月8日訊,彭博社知名記者馬克·古爾曼在《Power On》通訊中揭示,蘋果公司正逐步轉變其傳統的“年度更新”發布模式,邁向更為靈活的產品發布策略
    的頭像 發表于 10-08 16:46 ?1010次閱讀

    使用TM4C129x 微控制器為 TMP1826實現單線枚舉功能應用說明

    電子發燒友網站提供《使用TM4C129x 微控制器為 TMP1826實現單線枚舉功能應用說明.pdf》資料免費下載
    發表于 09-12 11:10 ?0次下載
    使用TM4C129x 微控制器為 TMP1826實現單線<b class='flag-5'>枚舉</b>功能應用說明

    設備管理——先進的工業設備管理模式策略

    在設備老化、故障率高、零部件供應不及時等問題中,先進的設備管理模式策略被廣泛應用。化工企業在設備管理方面采取優化措施,提高了維修效率和質量。
    的頭像 發表于 08-28 09:36 ?642次閱讀
    設備管理——先進的工業設備管理<b class='flag-5'>模式</b>與<b class='flag-5'>策略</b>

    在Ubuntu 20.04上使用USB 3時遇到了FX3無法枚舉的情況,怎么解決?

    *)CyFxUSB30DeviceDscr`) 中使用。在 Ubuntu 20.04 中是否存在任何已知問題,或者枚舉無法完成的原因? 我們在使用 Ubuntu 18.04 時沒有遇到這個問題。 USB2 可以正常工作。 還附上了 FX3 插入 Ubuntu 20.0
    發表于 07-26 08:26

    esp8266如何修改枚舉在編譯器中的字節寬度?

    在移植一個項目到esp8266上,這個項目原來平臺的編譯器中,enum枚舉占的字節數是1,但是到了esp的平臺,發現編譯器會編譯枚舉為4個字節,如何修改此編譯器選項?
    發表于 07-12 08:16

    5G商業模式:成功與挑戰,破局策略探討

    更看重實際成效,如‘提質、增效、降本’的實現。若無此支撐,即便有再優秀的5G,也會選擇Wi-Fi。”某企業家直言。這無疑揭示了企業選擇新技術時的核心關注點。   自5G牌照發放以來,我國
    的頭像 發表于 06-05 17:11 ?917次閱讀

    為什么可以將一個GPIO引腳同時配置為輸入輸出模式呢?

    的一系列高低電平。 那么對于GPIO6而言,在發送起始信號的時候,是輸出模式,接收信號的時候是輸入模式,也就是說需要將一個引腳同時配置為輸入輸出模式注意到,在gpio_mod
    發表于 06-05 07:37

    FX3使用DMA模式的話,有什么方法可以讓獲得串口接收到的數據?

    你好,想問一下,串口如果使用DMA模式的話,有什么方法可以讓獲得串口接收到的數據,除了函數getbuffer以及DMA通道回調事件觸發的時候能夠獲得其handle的buffer。這兩種方法雖然
    發表于 05-28 07:28

    Saturday只是一個枚舉元素啊,而today是一個枚舉變量,為什么他倆所占的內存空間大小是一樣的? [

    是4; 2.sizeof( today )的大小也是4; Saturday只是一個枚舉元素啊,而today是一個枚舉變量,為什么他倆所占的內存空間大小是一樣的? [/td] 以下內容為評論
    發表于 05-10 07:07
    主站蜘蛛池模板: 久操视频在线观看 | 一本到在线观看视频不卡 | 成人a毛片免费全部播放 | 天天躁夜夜躁 | 人人干人人玩 | 狠狠干干 | 久久精品视频免费播放 | 亚洲视频一区二区三区 | 91色爱| 欧美日本一区二区 | jinv在线视频 | 天堂电影在线观看免费入口 | 成人精品福利 | 国产小视频在线免费 | 俺去久久| 亚欧洲乱码专区视频 | 亚洲天堂电影在线观看 | 亚洲电影在线 | 99久久精品免费看国产 | 午夜欧美成人久久久久久 | 韩国三级日本三级在线观看 | 女人张开腿等男人桶免费视频 | 激情开心婷婷 | 国产色网 | 色老头·com| 人人玩人人添天天爽 | 亚洲国产精品第一区二区 | 亚洲天堂免费观看 | 色www亚洲国产张柏芝 | 操综合| 日本黄色视 | 黄色工厂在线播放 | 大尺度免费高清在线观看视频 | 色吧色吧色吧网 | 欧美 变态 另类 人妖班 | 国产精品夜夜春夜夜爽久久 | 色视频免费版高清在线观看 | 丁香婷婷激情综合 | 五月婷婷视频在线观看 | 日本色免费| 久久夜夜操 |