返回顶部
首页 > 资讯 > 前端开发 > JavaScript >怎么彻底干掉代码中的if else
  • 852
分享到

怎么彻底干掉代码中的if else

2024-04-02 19:04:59 852人浏览 八月长安
摘要

本篇内容主要讲解“怎么彻底干掉代码中的if else”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么彻底干掉代码中的if else”吧!恶心的 if-else

本篇内容主要讲解“怎么彻底干掉代码中的if else”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么彻底干掉代码中的if else”吧!

恶心的 if-else

假设我们要做一个外卖平台,有这样的需求:

  1. 外卖平台上的某家店铺为了促销,设置了多种会员优惠,其中包含超级会员折扣 8 折、普通会员折扣 9 折和普通用户没有折扣三种。

  2. 希望用户在付款的时候,根据用户的会员等级,就可以知道用户符合哪种折扣策略,进而进行打折,计算出应付金额。

  3. 随着业务发展,新的需求要求专属会员要在店铺下单金额大于 30 元的时候才可以享受优惠。

  4. 接着,又有一个变态的需求,如果用户的超级会员已经到期了,并且到期时间在一周内,那么就对用户的单笔订单按照超级会员进行折扣,并在收银台进行强提醒,引导用户再次开通会员,而且折扣只进行一次。

那么,我们可以看到以下伪代码:

public BigDecimal calPrice(BigDecimal orderPrice, String buyerType) {      if (用户是专属会员) {         if (订单金额大于30元) {             returen 7折价格;         }     }      if (用户是超级会员) {         return 8折价格;     }      if (用户是普通会员) {         if(该用户超级会员刚过期并且尚未使用过临时折扣){             临时折扣使用次数更新();             returen 8折价格;         }         return 9折价格;     }     return 原价; }

以上,就是对于这个需求的一段价格计算逻辑,使用伪代码都这么复杂,如果是真的写代码,那复杂度可想而知。

这样的代码中,有很多 if-else,并且还有很多的 if-else 的嵌套,无论是可读性还是可维护性都非常低。那么,如何改善呢?

策略模式

接下来,我们尝试引入策略模式来提升代码的可维护性和可读性。

首先,定义一个接口:

 public interface UserPayService {           public BigDecimal quote(BigDecimal orderPrice); }

接着定义几个策略类:

 public class ParticularlyVipPayService implements UserPayService {      @Override     public BigDecimal quote(BigDecimal orderPrice) {          if (消费金额大于30元) {             return 7折价格;         }     } }  public class SuperVipPayService implements UserPayService {      @Override     public BigDecimal quote(BigDecimal orderPrice) {         return 8折价格;     } }  public class VipPayService implements UserPayService {      @Override     public BigDecimal quote(BigDecimal orderPrice) {         if(该用户超级会员刚过期并且尚未使用过临时折扣){             临时折扣使用次数更新();             returen 8折价格;         }         return 9折价格;     } }

引入了策略之后,我们可以按照如下方式进行价格计算:

 public class Test {      public static void main(String[] args) {         UserPayService strategy = new VipPayService();         BigDecimal quote = strategy.quote(300);         System.out.println("普通会员商品的最终价格为:" + quote.doubleValue());          strategy = new SuperVipPayService();         quote = strategy.quote(300);         System.out.println("超级会员商品的最终价格为:" + quote.doubleValue());     } }

以上,就是一个例子,可以在代码中 New 出不同的会员的策略类,然后执行对应的计算价格的方法。

但是,真正在代码中使用,比如在一个 WEB 项目中使用,上面这个 Demo 根本没办法直接用。

首先,在 Web 项目中,上面我们创建出来的这些策略类都是被 spring 托管的,我们不会自己去 New 一个实例出来。

其次,在 Web  项目中,如果真要计算价格,也是要事先知道用户的会员等级,比如从数据库中查出会员等级,然后根据等级获取不同的策略类执行计算价格方法。

那么,Web 项目中真正的计算价格的话,伪代码应该是这样的:

 public BigDecimal calPrice(BigDecimal orderPrice,User user) {       String vipType = user.getVipType();       if (vipType == 专属会员) {         //伪代码:从Spring中获取超级会员的策略对象         UserPayService strategy = Spring.getBean(ParticularlyVipPayService.class);         return strategy.quote(orderPrice);      }       if (vipType == 超级会员) {         UserPayService strategy = Spring.getBean(SuperVipPayService.class);         return strategy.quote(orderPrice);      }       if (vipType == 普通会员) {         UserPayService strategy = Spring.getBean(VipPayService.class);         return strategy.quote(orderPrice);      }      return 原价; }

通过以上代码,我们发现,代码可维护性和可读性好像是好了一些,但是好像并没有减少 if-else 啊。

但是,策略模式的使用上,还是有一个比较大的缺点的:客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。

也就是说,虽然在计算价格的时候没有 if-else 了,但是选择具体的策略的时候还是不可避免的还是要有一些 if-else。

另外,上面的伪代码中,从 Spring 中获取会员的策略对象我们是伪代码实现的,那么代码到底该如何获取对应的 Bean 呢?

接下来我们看如何借助 Spring 和工厂模式,解决上面这些问题。

工厂模式

为了方便我们从 Spring 中获取 UserPayService 的各个策略类,我们创建一个工厂类:

 public class UserPayServiceStrategyFactory {      private static Map<String,UserPayService> services = new ConcurrentHashMap<String,UserPayService>();      public  static UserPayService getByUserType(String type){         return services.get(type);     }      public static void reGISter(String userType,UserPayService userPayService){         Assert.notNull(userType,"userType can't be null");         services.put(userType,userPayService);     } }

这个 UserPayServiceStrategyFactory 中定义了一个 Map,用来保存所有的策略类的实例,并提供一个 getByUserType  方法,可以根据类型直接获取对应的类的实例。还有一个 Register 方法,这个后面再讲。

有了这个工厂类之后,计算价格的代码即可得到大大的优化

 public BigDecimal calPrice(BigDecimal orderPrice,User user) {       String vipType = user.getVipType();      UserPayService strategy = UserPayServiceStrategyFactory.getByUserType(vipType);      return strategy.quote(orderPrice); }

以上代码中,不再需要 if-else 了,拿到用户的 vip 类型之后,直接通过工厂的 getByUserType 方法直接调用就可以了。

通过策略+工厂,我们的代码很大程度的优化了,大大提升了可读性和可维护性。

但是,上面还遗留了一个问题,那就是 UserPayServiceStrategyFactory 中用来保存所有的策略类的实例的 Map  是如何被初始化的?各个策略的实例对象如何塞进去的呢?

Spring Bean 的注册

还记得我们前面定义的 UserPayServiceStrategyFactory 中提供了的 Register 方法吗?他就是用来注册策略服务的。

接下来,我们就想办法调用 Register 方法,把 Spring 通过 ioc 创建出来的 Bean 注册进去就行了。

这种需求,可以借用 Spring 中提供的 InitializingBean 接口,这个接口为 Bean 提供了属性初始化后的处理方法。

它只包括 afterPropertiesSet 方法,凡是继承该接口的类,在 Bean 的属性初始化后都会执行该方法。

那么,我们将前面的各个策略类稍作改造即可:

 @Service public class ParticularlyVipPayService implements UserPayService,InitializingBean {      @Override     public BigDecimal quote(BigDecimal orderPrice) {          if (消费金额大于30元) {             return 7折价格;         }     }      @Override     public void afterPropertiesSet() throws Exception {         UserPayServiceStrategyFactory.register("ParticularlyVip",this);     } }  @Service public class SuperVipPayService implements UserPayService ,InitializingBean{      @Override     public BigDecimal quote(BigDecimal orderPrice) {         return 8折价格;     }      @Override     public void afterPropertiesSet() throws Exception {         UserPayServiceStrategyFactory.register("SuperVip",this);     } }  @Service   public class VipPayService implements UserPayService,InitializingBean {      @Override     public BigDecimal quote(BigDecimal orderPrice) {         if(该用户超级会员刚过期并且尚未使用过临时折扣){             临时折扣使用次数更新();             returen 8折价格;         }         return 9折价格;     }      @Override     public void afterPropertiesSet() throws Exception {         UserPayServiceStrategyFactory.register("Vip",this);     } }

只需要每一个策略服务的实现类都实现 InitializingBean 接口,并实现其 afterPropertiesSet 方法,在这个方法中调用  UserPayServiceStrategyFactory.register 即可。

这样,在 Spring 初始化的时候,当创建 VipPayService、SuperVipPayService 和  ParticularlyVipPayService 的时候,会在 Bean 的属性初始化之后,把这个 Bean 注册到  UserPayServiceStrategyFactory 中。

以上代码,其实还是有一些重复代码的,这里面还可以引入模板方法模式进一步精简,这里就不展开了。

还有就是,UserPayServiceStrategyFactory.register  调用的时候,第一个参数需要传一个字符串,这里的话其实也可以优化掉。

比如使用枚举,或者在每个策略类中自定义一个 getUserType 方法,各自实现即可。

到此,相信大家对“怎么彻底干掉代码中的if else”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: 怎么彻底干掉代码中的if else

本文链接: https://lsjlt.com/news/85305.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么彻底干掉代码中的if else
    本篇内容主要讲解“怎么彻底干掉代码中的if else”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么彻底干掉代码中的if else”吧!恶心的 if-else...
    99+
    2024-04-02
  • 怎么干掉if else
    这篇文章主要介绍“怎么干掉if else”,在日常操作中,相信很多人在怎么干掉if else问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么干掉if else”的疑惑有所帮...
    99+
    2024-04-02
  • Spring Boot怎么干掉 if else
    本篇内容介绍了“Spring Boot怎么干掉 if else”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!需求这里虚拟一个业务需求,让大家...
    99+
    2023-06-19
  • 怎么优化if-else代码结构
    本篇内容主要讲解“怎么优化if-else代码结构”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么优化if-else代码结构”吧!需求写一个 returnWee...
    99+
    2024-04-02
  • 如何优化Java代码中大量的if/else
    这篇文章主要介绍了如何优化Java代码中大量的if/else的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何优化Java代码中大量的if/else文章都会有所收获,下面我们一起来看看吧。观点一(灵剑)前期迭代...
    99+
    2023-07-05
  • windows上怎么干净彻底的卸载oracle
    1.关闭oracle所有的服务。可以在windows的服务管理器中关闭;2.打开注册表:regedit 打开路径:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Se...
    99+
    2024-04-02
  • 一招教你优化Java代码中大量的if/else
    目录观点一(灵剑)1. 提前return2. 策略模式2.1 多态2.2 枚举3. 学会使用 Optional4. 数组小技巧观点二(IT技术控)观点一(灵剑) 前期迭代懒得优化,来...
    99+
    2023-03-24
    Java优化if else Java if else
  • C++中的If Else语句怎么使用
    这篇文章主要介绍“C++中的If Else语句怎么使用”,在日常操作中,相信很多人在C++中的If Else语句怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++中的If Else语句怎么使用”的疑...
    99+
    2023-06-15
  • HTML中if注释代码怎么用
    这篇文章主要为大家展示了“HTML中if注释代码怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“HTML中if注释代码怎么用”这篇文章吧。 在html音讯...
    99+
    2024-04-02
  • win7右下角操作中心带红叉的小白旗子怎么彻底去掉?
    安装完Windows7系统后,在桌面右下角任务栏通知区里面,大家能看到一个带红叉的白色小旗帜,对于强迫症朋友或是有点电脑洁癖的人是看不得的,总想把它去掉。那么win7右下角操作中心带红叉的小白旗子怎么彻底去掉方法其实很简...
    99+
    2023-06-06
    win7右下角操作中心的小旗子 旗子 红叉 中心 操作
  • 怎么写出干净的JS代码
    本篇内容介绍了“怎么写出干净的JS代码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. 将数字定义为常量...
    99+
    2024-04-02
  • web开发中怎么写出优质干净的代码
    这篇文章主要介绍“web开发中怎么写出优质干净的代码”,在日常操作中,相信很多人在web开发中怎么写出优质干净的代码问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”web开发中...
    99+
    2024-04-02
  • 聊聊Python代码中if __name__ == ‘__main__‘的作用是什么
    目录Python中if __name__ == ‘__main__‘作用补充:if __name__ == '__main__':的运行原理总...
    99+
    2024-04-02
  • c语言中if语句是怎么变成汇编代码的详解
    目录 1. 要编译的测试代码: 2. 词法分析3. 语法分析4. 代码生成4.1 gen_expr4.2 cmp_zero4.3 println(" je .L.else.%d", ...
    99+
    2024-04-02
  • 怎么用vbs产生的若干个随机数并写入到一个.txt中的代码
    小编给大家分享一下怎么用vbs产生的若干个随机数并写入到一个.txt中的代码,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!代码如下:Set a=WScript.C...
    99+
    2023-06-08
  • HTML中的代码怎么注释
    这篇文章给大家分享的是有关HTML中的代码怎么注释的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。   HTML注释   在HTML代码中,<!--和-->标签之间...
    99+
    2024-04-02
  • 怎么关闭php中的伪静态代代码
    这篇文章主要介绍了怎么关闭php中的伪静态代代码的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么关闭php中的伪静态代代码文章都会有所收获,下面我们一起来看看吧。Apache服务器Apache服务器是Web服...
    99+
    2023-07-05
  • 怎么样把gitee中的代码导入
    Github,解决代码托管平台迁移问题随着互联网技术的不断发展,代码托管平台也在不断涌现和更新。在使用过程中,有时可能会需要将自己的代码从一个平台转移到另一个平台,比如把Gitee中的代码导入Github中。本文将介绍如何实现这个过程,帮助...
    99+
    2023-10-22
  • github中怎么上传自己的代码
    在数字化的今天,程序员们对于代码的管理不可谓不重要。在代码管理工具中,最流行的莫过于github了。那么,当你有需要在github上上传自己的代码时,该怎么做呢?下面,本文将为你详细介绍如何在github上上传自己的代码。第一步:创建仓库在...
    99+
    2023-10-22
  • 怎么修改PHP中的按钮代码
    这篇文章主要介绍“怎么修改PHP中的按钮代码”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么修改PHP中的按钮代码”文章能帮助大家解决问题。按钮通常用于网站和 Web 应用程序中的交互性功能,如提...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作