保健励志美文体育育儿作文
投稿投诉
作文动态
热点娱乐
育儿情感
教程科技
体育养生
教案探索
美文旅游
财经日志
励志范文
论文时尚
保健游戏
护肤业界

更优雅地实现策略模式

  一、为什么讲策略模式
  策略模式,应该是工作中比较常用的设计模式,调用方自己选择用哪一种策略完成对数据的操作,也就是一个类的行为或其算法可以在运行时更改
  我个人的理解是将一些除了过程不同其他都一样的函数封装成策略,然后调用方自己去选择想让数据执行什么过程策略。常见的例子为根据用户分类推荐不同的排行榜(用户关注点不一样,推荐榜单就不一样)
  和单例模式一样,随着时间发展,我不再推荐经典策略模式,更推荐简单策略用枚举策略模式,复杂地用工厂策略模式。下面引入一个例子,我们的需求是:对一份股票数据列表,给出低价榜、高价榜、涨幅榜。这其中只有排序条件的区别,比较适合作为策略模式的例子二、经典策略模式
  数据DTODatapublicclassStock{股票交易代码privateStringcode;现价privateDoubleprice;涨幅privateDoublerise;}
  抽象得到的策略接口publicinterfaceStrategy{将股票列表排序paramsource源数据return排序后的榜单ListStocksort(ListStocksource);}
  实现我们的策略类高价榜publicclassHighPriceRankimplementsStrategy{OverridepublicListStocksort(ListStocksource){returnsource。stream()。sorted(Comparator。comparing(Stock::getPrice)。reversed())。collect(Collectors。toList());}}低价榜publicclassLowPriceRankimplementsStrategy{OverridepublicListStocksort(ListStocksource){returnsource。stream()。sorted(Comparator。comparing(Stock::getPrice))。collect(Collectors。toList());}}高涨幅榜publicclassHighRiseRankimplementsStrategy{OverridepublicListStocksort(ListStocksource){returnsource。stream()。sorted(Comparator。comparing(Stock::getRise)。reversed())。collect(Collectors。toList());}}
  经典的Context类,publicclassContext{privateStrategystrategy;publicvoidsetStrategy(Strategystrategy){this。strategystrategy;}publicListStockgetRank(ListStocksource){returnstrategy。sort(source);}}
  于是我们顺礼成章地得到调用类榜单实例RankServiceImplServicepublicclassRankServiceImpl{dataService。getSource()提供原始的股票数据ResourceprivateDataServicedataService;前端传入榜单类型,返回排序完的榜单paramrankType榜单类型return榜单数据publicListStockgetRank(StringrankType){创建上下文ContextcontextnewContext();这里选择策略switch(rankType){caseHighPrice:context。setStrategy(newHighPriceRank());break;caseLowPrice:context。setStrategy(newLowPriceRank());break;caseHighRise:context。setStrategy(newHighRiseRank());break;default:thrownewIllegalArgumentException(rankTypenotfound);}然后执行策略returncontext。getRank(dataService。getSource());}}
  我们可以看到经典方法,创建了一个接口、三个策略类,还是比较啰嗦的。调用类的实现也待商榷,新增一个策略类还要修改榜单实例(可以用抽象工厂解决,但是复杂度又上升了)。加之我们有更好的选择,所以此处不再推荐经典策略模式三、基于枚举的策略模式
  这里对这种简单的策略,推荐用枚举进行优化。枚举的本质是创建了一些静态类的集合。
  我下面直接给出例子,大家可以直观感受一下
  枚举策略类publicenumRankEnum{以下三个为策略实例HighPrice{OverridepublicListStocksort(ListStocksource){returnsource。stream()。sorted(Comparator。comparing(Stock::getPrice)。reversed())。collect(Collectors。toList());}},LowPrice{OverridepublicListStocksort(ListStocksource){returnsource。stream()。sorted(Comparator。comparing(Stock::getPrice))。collect(Collectors。toList());}},HighRise{OverridepublicListStocksort(ListStocksource){returnsource。stream()。sorted(Comparator。comparing(Stock::getRise)。reversed())。collect(Collectors。toList());}};这里定义了策略接口publicabstractListStocksort(ListStocksource);}
  对应的调用类也得以优化,榜单实例RankServiceImplServicepublicclassRankServiceImpl{dataService。getSource()提供原始的股票数据ResourceprivateDataServicedataService;前端传入榜单类型,返回排序完的榜单paramrankType榜单类型形似RankEnum。HighPrice。name()return榜单数据publicListStockgetRank(StringrankType){获取策略,这里如果未匹配会抛IllegalArgumentException异常RankEnumrankRankEnum。valueOf(rankType);然后执行策略returnrank。sort(dataService。getSource());}}
  可以看到,如果策略简单的话,基于枚举的策略模式优雅许多,调用方也做到了0修改,但正确地使用枚举策略模式需要额外考虑以下几点。枚举的策略类是公用且静态,这意味着这个策略过程不能引入非静态的部分,扩展性受限策略模式的目标之一,是优秀的扩展性和可维护性,最好能新增或修改某一策略类时,对其他类是无改动的。而枚举策略如果过多或者过程复杂,维护是比较困难的,可维护性受限四、基于工厂的策略模式
  为了解决良好的扩展性和可维护性,我更推荐以下利用spring自带beanFactory的优势,实现一个基于工厂的策略模式。
  策略类改动只是添加了Service注解,并指定了Service的value属性高价榜注意申明Service。valueHighPrice,他是我们的key,下同Service(HighPrice)publicclassHighPriceRankimplementsStrategy{OverridepublicListStocksort(ListStocksource){returnsource。stream()。sorted(Comparator。comparing(Stock::getPrice)。reversed())。collect(Collectors。toList());}}低价榜Service(LowPrice)publicclassLowPriceRankimplementsStrategy{OverridepublicListStocksort(ListStocksource){returnsource。stream()。sorted(Comparator。comparing(Stock::getPrice))。collect(Collectors。toList());}}高涨幅榜Service(HighRise)publicclassHighRiseRankimplementsStrategy{OverridepublicListStocksort(ListStocksource){returnsource。stream()。sorted(Comparator。comparing(Stock::getRise)。reversed())。collect(Collectors。toList());}}
  调用类修改较大,接入借助spring工厂特性,完成策略类ServicepublicclassRankServiceImpl{dataService。getSource()提供原始的股票数据ResourceprivateDataServicedataService;利用注解Resource和Autowired特性,直接获取所有策略类keyService的valueResourceprivateMapString,StrategyrankMap;前端传入榜单类型,返回排序完的榜单paramrankType榜单类型和Service注解的value属性一致return榜单数据publicListStockgetRank(StringrankType){判断策略是否存在if(!rankMap。containsKey(rankType)){thrownewIllegalArgumentException(rankTypenotfound);}获得策略实例StrategyrankrankMap。get(rankType);执行策略returnrank。sort(dataService。getSource());}}
  若读者使用的不是Spring,也可以找找对应框架的工厂模式实现,或者自己实现一个抽象工厂
  工厂策略模式会比枚举策略模式啰嗦,但也更加灵活、易扩展性和易维护。故简单策略推荐枚举策略模式,复杂策略才推荐工厂策略模式
  本文来自https:www。cnblogs。comdechinphypdictclass。html

我的旅行记四年级作文我的名字叫做《不知道的世界》。我出自郑平和刘子午的手中,被校讯通活动中的书香班级五(三)班给拿走了,我的第一个主人就是一个长头发的书虫姐姐,她把我请回了家,从此我变得幸福极了。……世说新语读书笔记两篇《世说新语》读书笔记(一)阅读《世说新语文学篇》,更多的感触是古人的那种良好的学习态度和浓厚的学习学习氛围,《世说新语》读书笔记2000字。其中让我感触颇深的一段记载是说……买自行车小学作文500字耶!太高兴了,期盼了五年的自行车,今天妈妈终于答应给我买了。吃完午饭,妈妈就去给我买自行车,爸爸送我去上学。一路上,我觉得时间过得真慢,恨不得插双翅膀飞过去,再飞回来。……空气净化器和具有新风净化功能的空调买哪个更好空气净化器和具有新风、净化功能的空调,买哪个更好呢?空调企业以空调为平台,将新风、净化功能纳入到空调中,因此诞生了具有新风、净化能力的空调,一个全面改善空气质量的新品类。……保护世界文化遗产作文遗产已经成为历史上的耀眼明珠,我们绝不能让它停留在现在,停留在历史上。让文化遗产成为一幅壮美的画卷,一如谱写在旷野的诗篇。下面是小编为大家准备的保护世界文化遗产作文,希望大家能……想买台折叠屏,预算一万以下,有没有懂的人推荐一下?在折叠屏手机上,如今小米、oppo、华为、三星、摩托罗拉都有机型!最便宜的是OPPOFindN售价7699元,是横向折叠屏的手机!所以想要购买折叠屏手机,如今在折叠屏形式上要做……父亲的病读后感《父亲的病》回忆儿时为父亲延医治病的情景,描述了几位名医的行医态度、作风、开方等种种表现。揭示了这些人巫医不分、故弄玄虚、勒索钱财、草菅人命的实质。故事发生在鲁迅年轻时的……关于描写班长的作文大全班长是负责协助班主任一起管理班级的。以下是小编整理的关于描写班长的作文大全,欢迎阅读。篇一:我们班的班长叮铃铃,叮铃铃,下课了,同学们像一支支离弦之箭冲出教室,奔向操场。……狮子和大象的故事导语:一个障碍,就是一个新的已知条件,只要愿意,任何一个障碍,都会成为一个超越自我的契机。下面是yuwenmi小编为大家整理的哲理故事,欢迎阅读与借鉴,谢谢!狮子和大象的……业务员每天出门要带两部iPhone一部安卓机两个充电宝和三张感谢您的阅读!我现在确实是这样的操作:虽然不是业务员,每天工作原因,都必须带两部手机出门,一部手机工作生活、一部手机娱乐休闲。当然,充电宝我是不带的,之前用的是小米充电宝……这些天优质作文欣赏这个春节在不知不觉中就过了,现在回想起来好像还是昨天的事,可是今天已经初四了。而这些天呢?玩得有点过火了,妈妈说玩就玩,但是要有个度,不能整天想着去外面玩。我说知道了,又不是小……写作基础写人作文方法要求写人,是小学作文训练的基本功之一。在记叙文中,人和事是不可分的,关键是看题目如何要求。要求写事的题目,文中的人要为事服务;要求写人的题目,文中的事必须为人服务。写人为主的记叙文……
看似寻常又是一年春花落幕的时候了。樱花桃花的花瓣不知被风吹到了那里,代替它们的是一树碧绿的叶子,有时会在风中沙沙作响。杜鹃开得正盛,这种别名映山红的花,在初夏的阳光下笑得一派明艳……领鹊科技完成亿元A轮融资由IDG资本领投建筑机器人研发、制造与运营商领鹊科技宣布完成亿元A轮融资,本轮融资由IDG资本领投,老股东AtypicalVentures跟投。领鹊科技上一轮融资在2021年3月,投资方……实用小学毕业作文500字九篇在学习、工作乃至生活中,许多人都有过写作文的经历,对作文都不陌生吧,作文是人们以书面形式表情达意的言语活动。那么,怎么去写作文呢?以下是小编为大家收集的小学毕业作文500字9篇……做家务的小作文家务,又称家事、家政,陕西人也叫过日子、过日月、过光景等。家务内容复杂,既有开门七件事:柴、米、油、盐、酱、醋、茶,又有缝新补烂。小编精心为你整理了做家务的小作文,希望对你有所……全球5国自动驾驶交通事故责任如何认定?(2)美国其他州针对自动驾驶汽车也推出或提出了相应的法律规定和法案。如德州法律规定,自动驾驶汽车在所有行程中完全由自动驾驶系统操作,不受传统车辆法律或人类司机操作车辆的规定约束……一加新机瞄准中端市场,借力OPPO加速覆盖线下渠道记者陆柯言与OPPO合并后,曾经小而美的一加正在加速走向大众市场。就在上周,一加发布了全新的Ace系列,首款产品一加Ace定位中端市场,起售价2499元,主打性能和……珍惜每一次批评作文在我们平凡的日常里,大家总少不了接触作文吧,作文是由文字组成,经过人的思想考虑,通过语言组织来表达一个主题意义的文体。一篇什么样的作文才能称之为优秀作文呢?以下是小编为大家整理……中秋作文700字中秋,是中国的传统节日,在农历的八月十五的,在这一天家人们都会团聚起来,一起品尝自己家里所做的美食,有诗句来比喻:ldquo;谕尚书镇牛淆,中秋夕与左右微服泛江rdquo;。……我的课余生活作文450字我课余的生活可丰富了,有读书、练字、打乒乓球、跳舞、游泳、旅游hellip;hellip;但我最喜欢非读书莫属。书里有无穷无尽的知识,让我们在学习一天后,从巨大的压力中挣……多国加紧小行星探测和防御研究来源:环球时报【环球时报综合报道】根据国际小行星中心的数据,在太阳系中已经发现的小行星超过102。6万颗。这些小行星的存在带来了撞击地球的隐患。虽然小行星撞击地球发生概率……推特(TWTR。US)联合创始人PatrickDorsey埃推特(TWTR。US)联合创始人PatrickDorsey:埃隆马斯克(收购推特)是我所信任的唯一解决方案。Twitter(TWTR。US)公司简介:Twitter,In……调皮的弟弟小学作文范文我有两个调皮的弟弟,他们很可爱!大弟弟一直以他的柳叶眉为傲;小弟则以他白净的小脸蛋为荣。一天,我们正在玩,忽然,下起了雨。我连忙用双手抱住头,对弟弟说:快,跟我去避避雨。……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网