前言

这两天在知乎上看到一篇文章名叫《一个程序员的水平能差到什么程度?》这上面写的代码确实让看的人当做饭后笑话的谈资,让下一个接盘的人又磨刀霍霍向猪羊的冲动

里面大部分的吐槽都是针对于if else 无作为的使用以及滥用的吐槽,if …else if … else…这确实是我们在各种项目研发中的一个利器,但是一旦他过于多,就会使逻辑混乱,让代码的可读性大大下降,并且我发现在我以前写的项目中也存在许多的if…else…因而我下定决定,画了一天时间研究,打算使用策略模式来代替过多的if else。

策略模式的介绍

策略模式
引入百科的解释:策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。

策略模式:顾名思义就是当要在不同的情况下做出该情况下所适用的策略,按照面向对象的是思想就是,就使用继承和多态机制,实现同一行为在不同场景下具备不同实现。

策略模式的本质:分离算法,选择实现。

主要解决

从上述的策略模式的本质中的选择实现是不是可以联想到if…else if… else…没错,在有多种算法相似的情况下,使用 if…else 或 switch…case 所带来的复杂性和臃肿性。

优缺点

优点

  • 策略的多样性,能够自由切换
  • 有效的避免了多重判断,提高了代码的可读性,扩展性,封装性
  • 降低了操作难度以及错误率。

缺点

  • 增加了开发难度,策略类数量增多,并且所要策略类都要对外开放,以便客户端访问

你还在用if else吗?

这里给大家举一个典型的例子
我们每天扫码支付,选用支付方式,选择的微信,支付宝,或者是直接银行卡支付。想必大家已经屡见不鲜了。
那我们现在我们需要做一个支付系统,通过扫描二维码对一个商户进行付款,我们可以选用我们已经绑定的支付宝账号,微信,或者所绑定的银行,直接进行支付,由于每家商户不同,可能付款的时候可能也会有一些优惠政策的不同,并且他们为外界所提供的API也会有所不同。例如,支付宝可以使用红包进行抵用,直接使用银行卡付款,每家银行可能会有不同的折扣。具体情况比较复杂,这里就不做考虑,为了为接下来的策略模式做铺垫,我们这里就简单的分为,微信支付,支付宝支付,银行卡支付,抵用券支付。
我相信很多人拿到需求后,最先考虑的写法就是:

package pay;public class Example {public String selectPayWay(Integer payCode){if(PayWayEnum.WEICHAT_PAY.equals(payCode)){//do somethingreturn "微信支付成功";}else if(PayWayEnum.AL_PAY.equals(payCode)){// do somethingreturn "支付宝支付成功";}else if(PayWayEnum.CARD_PAY.equals(payCode)){// do somethingreturn "银行卡成功";}else if(PayWayEnum.PONIT_COUPON_PAY.equals(payCode)){// do somethingreturn "优惠券支付成功";}else {return "";}}}

可以看出上面四种不同的支付方式在同一个方法体内部,不利于扩展和维护,并且也不符合面向对象设计原则。对以上的代码使用策略模式进行代替,类图如下:


从 上面的UML 类图中,我们可以看到,策略模式 主要包含三种角色:

  • 上下文角色(Context):用来操作策略的上下文环境,屏蔽高层模块(客户端)对策略,算法的直接访问,封装可能存在的变化;
  • 抽象策略角色(Strategy):规定策略或算法的行为;
  • 具体策略角色(ConcreteStrategy):具体的策略或算法实现;

java代码实现具体如下

package strategy;public interface PayStrategy {String selectPayWay(Integer paycode);
}

规定具体策略行为

package strategy;public class PayContext {private PayStrategy payStrategy;public String selectPayWay(Integer payCode){payStrategy =  StrategyFactory.getInstance().create(payCode);return payStrategy.selectPayWay(payCode);}public PayStrategy getPayStrategy() {return payStrategy;}public void setPayStrategy(PayStrategy payStrategy) {this.payStrategy = payStrategy;}
}

支付宝付款实现类

package strategy.paystrategy;import strategy.PayStrategy;public class ALPayStrategy implements PayStrategy {@Overridepublic String selectPayWay(Integer paycode) {//do somethingreturn "支付宝支付成功";}
}

银行卡支付实现类

package strategy.paystrategy;import strategy.PayStrategy;public class CardPayStrategy implements PayStrategy {@Overridepublic String selectPayWay(Integer paycode) {//do somethingreturn "银行卡支付成功";}
}

点券支付实现类

package strategy.paystrategy;import strategy.PayStrategy;public class PointCouponPayStrategy implements PayStrategy {@Overridepublic String selectPayWay(Integer paycode) {//do somethingreturn "点券支付成功";}
}

微信支付实现类

package strategy.paystrategy;import strategy.PayStrategy;public class WeChatPayStrategy implements PayStrategy {@Overridepublic String selectPayWay(Integer paycode) {//do somethingreturn "微信支付成功";}}

创建策略类的工厂

package strategy;import pay.PayWayEnum;
import strategy.paystrategy.ALPayStrategy;
import strategy.paystrategy.CardPayStrategy;
import strategy.paystrategy.PointCouponPayStrategy;
import strategy.paystrategy.WeChatPayStrategy;import java.util.HashMap;
import java.util.Map;public class StrategyFactory {private static StrategyFactory factory = new StrategyFactory();private StrategyFactory(){}private static Map strategyMap = new HashMap<>(16);static {strategyMap.put(PayWayEnum.AL_PAY.getCode(),new ALPayStrategy());strategyMap.put(PayWayEnum.WEICHAT_PAY.getCode(),new WeChatPayStrategy());strategyMap.put(PayWayEnum.CARD_PAY.getCode(),new CardPayStrategy());strategyMap.put(PayWayEnum.PONIT_COUPON_PAY.getCode(),new PointCouponPayStrategy());}public PayStrategy create(Integer payCode){return (PayStrategy) strategyMap.get(payCode);}public static StrategyFactory getInstance(){return factory;}}

实现客户端

package strategy;public class Client {public static void main(String[] args) {PayContext payContext = new PayContext();System.out.println(payContext.selectPayWay(100));}
}

最后在贴一个枚举类

package pay;public enum PayWayEnum {/**微信支付*/WEICHAT_PAY("微信支付",100),/**支付宝支付*/AL_PAY("支付宝支付",101),/**银行卡支付*/CARD_PAY("银行卡支付",102),/**点券支付*/PONIT_COUPON_PAY("点券支付",103);private String msg;private Integer code;PayWayEnum(String msg, Integer code) {this.msg = msg;this.code = code;}public String getMsg() {return msg;}public Integer getCode() {return code;}
}

从上面代码中,我们可以看到,我们完全消除了对状态码进行判断的那些if…else的冗余代码,取而代之是直接由客户端决定使用哪种算法,然后交由上下文获取结果。极大的增强的了扩展性,隐藏了内部实现的细节,当然我们也可以看到,策略模式由于独立策略的实现,也使得系统内部增加了很多策略,对客户端来必须知道这些策略类实现的是那些策略,而且需要知道具体的策略条件。

然而在实际的生产环境中我们可能不会像示例代码这样干,在实际的生产环境中我们一般会结合spring来对我们所需的策略进行操作,这边我可以给大家有个具体的思路,大家可以通过这个思路来想想,自己在实际生产环境会怎样操作

整体思路:

  1. 首先和上面代码一样定义一个Strategy接口,其中有一个operation的函数交给具体业务去实现
  2. 根据自己的业务,会拥有很多的策略类实现该接口;将这些类注册到spring Bean容器中提供使用。
  3. 通过客户端传值,从spring容器中获取Strategy实例
  4. 最终来执行operation函数

好了这次的分享就到此结束啦,下次我在真正的开发项目中使用到了策略模式代替if else的话我会结合我的项目在给大家看下怎样在实际的生产环境中应用,感谢大家的阅读。

使用策略模式代替繁琐的if else相关推荐

  1. 设计模式学习(一)——策略模式

    2019独角兽企业重金招聘Python工程师标准>>> 前段时间买了一本书<Head First设计模式>,看了第一章后才对设计模式的概念有少许了解:它其实是开发过程中很 ...

  2. 设计模式(2)策略模式 (模式讲解+应用)

    博客新址,这里更有趣 目录 策略模式 为什么使用策略模式? 策略模式应用实例 策略模式 策略模式:建立行为族,将不同的行为分别封装,同时彼此可相互替代,算法的变化可以独立于使用者. 优点:提高了可复用 ...

  3. C语言,去你的策略模式!

    前言 这里先插一点题外话,在C语言中,实现封装.继承.隐藏.多态等等特性,是完全没有问题的.但是在使用过程中,必定是不如自带这些特性的语言方便好用的,比如C \java等. 一旦要通过C语言来实现各种 ...

  4. 《设计模式》之策略模式

    一.什么是策略模式? 比如对象的某个行为,在不同场景有不同实现方式,可以将这些行为的具体实现定义为一组策略,每个实现类实现种策略,在不同场景使用不同的实现,并且可以自由切换策略. 1.1.策略模式结构 ...

  5. 【设计模式2_工厂模式、策略模式】

    工厂模式 工厂模式与策略模式通常可以配合使用,成对出现,也是初学设计模式时常常分不清二者区别的原因. 简单工厂 业务场景需要根据传入的不同参数以获取对应的对象来处理各自的逻辑,很容易写出如下代码: v ...

  6. 策略模式代替if-else

    采用key-value的形式替换繁琐的if-else (高端大气上档次) if-else或switch写法: // if-else const onTabChange = (key: string) ...

  7. Java设计模式——策略模式(解决满屏的if/else)

    一.业务场景 项目需要对接支付系统,根据不同客户类型会有不同的支付方式,比如:支付宝.微信.银联.云闪付等等其他第三方支付平台,这个时候策略模式就大展身手了. 传统的if/else/switch 等等 ...

  8. 别在再满屏的 if、else 了,试试策略模式,真香!!

    你还在写满屏的 if/ else/ switch 之类的判断逻辑吗? 栈长在开发人员的代码中看过太多这样的低级代码了,真的太 low,极不好维护,本文栈长就教你如何用策略模式干掉 if/ else/ ...

  9. Java策略模式讲解以及示例

    策略模式(Strategy Patten) 什么是策略模式? 比如对象的某个行为,在不同场景有不同实现方式,可以将这些行为的具体实现定义为一组策略,每个实现类实现种策略,在不同场景使用不同的实现,并且 ...

  10. Spring实现策略模式

    通过Spring实现策略模式 当程序中使用太多的if/else/switch来处理不同类型的业务时,会变得极难维护,通过策略模式可以更容易的实现业务扩展和维护. 标准策略模式介绍 比如说对象的某个行为 ...

最新文章

  1. CPU飙高,频繁GC,怎么排查?
  2. JAVASE初级笔记
  3. word2vec的数据结构
  4. mysql数据库基本操作练习
  5. phpstorm安装_快速打造自己的PHPStorm主题
  6. jQuery 学习笔记(jQuery: The Return Flight)
  7. WPF中MVVM模式的 Event 处理
  8. Android系统(187)---最易懂的Activity启动模式详解
  9. vscode 模拟本地服务器打开文件,设置默认浏览器为chrome
  10. vue打开二级或者三级页面传输对象,再刷新浏览器数据丢失问题解决(vue使用router传递数据)
  11. .net 初学者。学习笔记 [获取varchar32主键的最大ID值]
  12. 【Modern Robotics】 Mechanics, Planning and Control现代机器人学:机构、规划与控制
  13. 紧急大项目的应付手法
  14. AH快递单打印管理软件
  15. Tomcat的appBase,docBase,path关系
  16. axis调用java实现webservice实例
  17. eclipse 打包springcloud 项目出错怎么解决
  18. 【音视频开发】基础知识:视频简介
  19. 【蓝桥云课】最大公约数与最小公倍数
  20. 步进电机T型和S型速度曲线

热门文章

  1. 【自然法则】群体智慧
  2. 郑州java工程师_郑州Java开发薪资很可观,学Java开发真的有前景?
  3. 信息学奥赛一本通(c++):2071:【例2.14】平均分
  4. Linux进程通信学习笔记
  5. 阿里云服务器购买和使用图文详解
  6. 2021年焊工(初级)考试内容及焊工(初级)考试试卷
  7. 对序列化后的buffer进行strlen操作, oh my god
  8. 安卓协议逆向 咸鱼 frida rpc 调用方案
  9. 深度学习工程师能力评估标准(Deep learning engineer capability evaluation standard)
  10. 2019河南理工大学计算机类分数线,2019河南考生多少分能上河南理工大学 历年录取分数线...