当前位置: 首页 > 科技观察

如何用策略模式简化if-else?

时间:2023-03-20 10:17:39 科技观察

大家好,我是北军。相信大家在日常开发中会经常写各种分支判断语句,比如if-else。分支多的时候,代码会显得臃肿,那么如何优化呢?1、什么是策略模式?定义一系列算法,封装每个算法,并使它们可以互换。策略让算法独立于使用它的客户而变化。StrategyPattern:定义一族算法类,分别封装每个算法,使它们可以相互替代。2.策略模式定义①上下文封装角色也称为上下文角色,作为前后封装之间的纽带,屏蔽高层模块对策略和算法的直接访问,封装可能的变化。②Strategyabstract策略角色策略和算法族的抽象,通常是一个接口,定义了每个策略或算法必须具备的方法和属性。③ConcreteStrategy具体策略角色在抽象策略中实现操作,该类包含具体的算法。3.策略模式通用代码publicclassContext{//抽象策略privateStrategystrategy=null;//设置特定策略的构造函数publicContext(Strategystrategy){this.strategy=strategy;}//封装策略方法publicvoiddoAnything(){this.strategy.doSomething();}}publicinterfaceStrategy{//策略模式的算法publicvoiddoSomething();}publicclassConcreteStrategy1implementsStrategy{@OverridepublicvoiddoSomething(){System.out.println("具体策略1");}}publicclassConcreteStrategy2implementsStrategy{@OverridepublicvoiddoSomething(){System.out.println("ConcreteStrategy2");}}Test:publicclassStrategyClient{publicstaticvoidmain(String[]args){//声明一个具体的策略Strategystrategy=newConcreteStrategy1();//声明上下文对象Contextcontext=newContext(strategy);//执行封装的方法context.doAnything();}}4。使用Strategy模式重写if-else假设我们要处理一个office文件,文件分为三种,分别为docx、xlsx、pptxWord文件、Excel文件、PPT文件根据文件后缀解析4.1常规写法publicclassOfficeHandler{publicvoidhandleFile(StringfilePath){if(filePath==null){return;}StringfileExtension=getFileExtension(文件路径);if(("docx").equals(fileExtension)){handlerDocx(filePath);}elseif(("xlsx").equals(fileExtension)){handlerXlsx(filePath);}elseif(("pptx").equals(fileExtension)){handlerPptx(filePath);}}publicvoidhandlerDocx(StringfilePath){System.out.println("处理docx文件");}publicvoidhandlerXlsx(StringfilePath){System.out.println("处理xlsx文件");}publicvoidhandlerPptx(StringfilePath){System.out.println("处理pptx文件");}privatestaticStringgetFileExtension(StringfilePath){//解析文件名得到文件扩展名,比如document.docx,返回docxStringfileExtension=filePath.substring(filePath.lastIndexOf(".")+1);返回文件扩展名;}}所有的处理逻辑都放在一个类中,会导致整个类特别大,false假设我们要添加一种新的处理类型。比如2007之前的office文件,后缀是doc/xls/ppt,那么我们还要加上elseif逻辑,这就违背了开闭原则。如何解决这个问题呢?回答策略模式4.2策略模式修改publicinterfaceOfficeHandlerStrategy{voidhandlerOffice(StringfilePath);}publicclassOfficeHandlerDocxStrategyimplementsOfficeHandlerStrategy{@OverridepublicvoidhandlerOffice(StringfilePath){System.out.println("处理docx");}}//省略OfficeHandlerXlsxStrategy/OfficeHandlerPptxStrategy类publicclassOfficeHandlerStrategyFactory{privatestaticfinalMapmap=newHashMap<>();static{map.put("docx",newOfficeHandlerDocxStrategy());map.put("xlsx",newOfficeHandlerXlsxStrategy());map.put("pptx",newOfficeHandlerPptxStrategy());}publicstaticOfficeHandlerStrategygetStrategy(Stringtype){returnmap.get(type);}}测试:publicclassOfficeHandlerStrategyClient{publicstaticvoidmain(String[]args){StringfilePath="C://file/123.xlsx";字符串类型=getFileExtension(文件路径);OfficeHandlerStrategy策略=OfficeHandlerStrategyFactory.getStrategy(type);strategy.handlerOffice(文件路径);}privatestaticStringgetFileExtension(StringfilePath){//解析文件名获取文件扩展名,如document.docx,返回docxStringfileExtension=filePath.substring(filePath.lastIndexOf(".")+1);返回文件扩展名;}}4.策略模式的优点①算法可以自由切换这是策略模式本身定义的。只要实现了抽象策略,它就成为策略家族的一员。通过封装角色来封装,保证对外提供“自由切换”的策略②避免使用多个条件判断来简化多个if-else,或者多个switch-case分支。③扩展性好添加一个策略,只需要实现一个接口。5.策略模式应用场景①多个类仅算法或行为略有不同的场景。②算法需要自由切换的场景。③需要屏蔽算法规则的场景。