一、策略模式 1。1策略模式概念 策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。 1。2策略模式结构 策略模式的结构包括三种角色:策略(Strategy):策略是一个接口,该接口定义算法标识。具体策略(ConcreteStrategy):具体策略是实现策略接口的类。具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体算法。上下文(Context):上下文是依赖于策略接口的类,即上下文包含有策略声明的变量。上下文中提供了一个方法,该方法委托策略变量调用具体策略所实现的策略接口中的方法。 策略模式接口的类图如下所示: 策略模式UML 1。3常规策略模式不足点 在我们平时写的策略模式代码中,具体采用哪个策略实现类,是在Context类中通过入参来判断的,如果随着需求扩展,需要增加一个新的策略实现类,必定要来修改Context类,这就违背了【开闭原则】。如果能做到:有新的策略实现需要增加时,只需要新建一个策略实现类,去实现策略接口就完事,其他旧代码完全不用修改。这才是我心目中的【开闭原则】,可喜的是,利用Autowired注解与策略模式搭配,就能实现这一目标。二、Autowired注解预热 2。1Autowired自动装配多个实例 平时我们一般都是通过Autowired自动装配单个实例,但这里我会告诉你,它也能自动装配多个实例。 2。2Autowired实现自动装配多个实例 用一个List集合接收IUser类型的参数ServicepublicclassUserService{AutowiredprivateListIUseruserList;AutowiredprivateSetIUseruserSet;AutowiredprivateMapString,IUseruserMap;publicvoidtest(){System。out。println(userList:userList);System。out。println(userSet:userSet);System。out。println(userMap:userMap);}} 增加一个controllerRequestMapping(u)RestControllerpublicclassUController{AutowiredprivateUserServiceuserService;RequestMapping(test)publicStringtest(){userService。test();returnsuccess;}} userList、userSet和userMap都打印出了两个元素,说明Autowired会自动把相同类型的IUser对象收集到集合中。 2。3利用Autowired自动装配多个实例与策略模式搭配 利用Autowired自动装配多个实例与策略模式来搭配使用,变种后的策略模式:不需要content类来按条件选择具体的策略类。一个策略接口,多个具体策略实现类。每个具体策略实现类,通过入参参数判断自己是否需要执行,如果不需要执行,直接返回。调用策略的client类,通过Autowired自动装配多个实例,一次性拿到所有策略实现类,通过循环调用这些策略实现类。有新的策略实现,新建新的具体实现类就可以了,不需要像以前一样去修改content类,真正实现了开闭原则。三、Autowired搭配策略模式实现 3。1需求背景 在我们平时开发的项目中,大部分都会有App站外推送的功能,通常,我们一般都会采用第三方推送集成平台,如某盟或某光。但我们项目为了更高的推送到达率以及更灵活的推送配置功能,我们采用了对接各厂商官方的推送平台的方式,比如对接华为、小米、Oppo等。这个需求场景就非常适合采用策略模式来开发,这次我们用Autowired搭配策略模式来实现。 3。2代码实现推送策略类publicinterfaceIPushStrategy{paramuserId:用户IDparammsg:推送消息paramsupplier:推送供应商returnbooleanpush(LonguserId,Stringmsg,Stringsupplier);}华为推送策略ServicepublicclassHuaWeiPushServiceimplementsIPushStrategy{Overridepublicbooleanpush(LonguserId,Stringmsg,Stringsupplier){if(HuaWei。equals(supplier)){System。out。println(华为推送给用户userId,推送消息:msg);returntrue;}returnfalse;}}Oppo推送策略ServicepublicclassOppoPushServiceimplementsIPushStrategy{Overridepublicbooleanpush(LonguserId,Stringmsg,Stringsupplier){if(Oppo。equals(supplier)){System。out。println(Oppo推送给用户userId,推送消息:msg);returntrue;}returnfalse;}}小米推送策略ServicepublicclassXiaoMiPushServiceimplementsIPushStrategy{Overridepublicbooleanpush(LonguserId,Stringmsg,Stringsupplier){if(XiaoMi。equals(supplier)){System。out。println(小米推送给用户userId,推送消息:msg);returntrue;}returnfalse;}}推送策略contextComponentpublicclassPushContextimplementsIPushStrategy{AutowiredprivateListIPushStrategypushStrategyList;Overridepublicbooleanpush(LonguserId,Stringmsg,Stringsupplier){booleansupplierMatchedfalse;for(IPushStrategypushStrategy:pushStrategyList){supplierMatchedpushStrategy。push(userId,msg,supplier);if(supplierMatched){break;}}returnsupplierMatched;}}Api(tags推送策略模式)RestControllerRequestMapping(strategy)publicclassTestController{ResourceprivatePushContextpushContext;ApiOperation(value推送)GetMapping(push)publicbooleanpush(){LonguserId273L;Stringmsg您有新的订单;StringsupplierHuaWei;调用的是华为推送实现策略returnpushContext。push(userId,msg,supplier);}} 3。3后续故事 声明:以下故事纯属虚构,如有雷同,纯属巧合。 突然,某一天,产品小姐姐跑过来说,我们今天要完成Vivo推送平台的开发和相关功能测试,今天上线,行不行? 这时,我以往心中的那一万匹马这次竟然不见了,我嘴角微微上扬,露出我富有职业素养、标准而又职业的微笑,回答道:行(男人不能说不行)。我回到工位,新建了一个Vivo推送的策略实现类并进行实现。 幸运的是,之前那些经过测试小妹妹九九八十一次测试好的推送功能代码,一行都不需要改动,保证了程序的稳定性,更降低了测试成本。此时,【开闭原则】在我的心中闪闪发光。