java如何消除太多的if else判断示例代码

1.简介

if判断语句是很多编程语言的重要组成部分。但是,若我们最终编写了大量嵌套的if语句,这将使得我们的代码更加复杂和难以维护。

让我们看看能否使用别的方式来做呢。

设计模式是为了更好的代码重用性,可读性,可靠性,可维护性,它有六大原则:

  • 单一职责原则(Single Responsibility Principle,简称SRP):该原则是针对类来说的,即一个类应该只负责一项职责.
  • 开放--封闭原则(The Open-Closed Principle简称OCP):是说软件实体(类、模块、函数等等)应该可以扩展,但是不可以修改。
  • 依赖倒转原则(Dependence Inversion Principle :针对接口编程,不要对实现编程
  • 里氏代换原则(Liskov Substitution Principle,简称LSP):里氏代换原则,子类型必须能够替换掉他们的父类型
  • 迪米特法则(Law of Demeter):如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用
  • 合成/聚合复用原则(Composition/Aggregation Principle],简称CARP):尽量使用合成/聚合,尽量不使用类继承。合成聚合是“has  a”的关系,而继承是“is  a”的关系。

2.示例if..else

public int calculate(int a, int b, String operator) {
 int result = Integer.MIN_VALUE;

 if ("add".equals(operator)) {
 result = a + b;
 } else if ("multiply".equals(operator)) {
 result = a * b;
 } else if ("divide".equals(operator)) {
 result = a / b;
 } else if ("subtract".equals(operator)) {
 result = a - b;
 } else if ("modulo".equals(operator)) {
 result = a % b;
 }
 return result;
}

switch-case

public int calculateUsingSwitch(int a, int b, String operator) {
 int result = 0;
 switch (operator) {
 case "add":
 result = a + b;
 break;
 case "multiply":
 result = a * b;
 break;
 case "divide":
 result = a / b;
 break;
 case "subtract":
 result = a - b;
 break;
 case "modulo":
 result = a % b;
 break;
 default:
 result = Integer.MIN_VALUE;
 }
 return result;
}

3.重构

3.1 工厂方式重构

抽象层Operation.java

public interface Operation {
 int apply(int a, int b);
}

加法实现Addition.java:

public class Addition implements Operation {
 @Override
 public int apply(int a, int b) {
 return a + b;
 }
}

减法实现Subtraction.java

public class Subtraction implements Operation {
 @Override
 public int apply(int a, int b) {
 return a - b;
 }
}

乘法实现Multiplication.java

public class Multiplication implements Operation {
 @Override
 public int apply(int a, int b) {
 return a\*b;
 }
}

除法实现Division.java

public class Division implements Operation {
 @Override
 public int apply(int a, int b) {
 return a / b;
 }
}

求余实现Modulo.java

public class Modulo implements Operation {
 @Override
 public int apply(int a, int b) {
 return a % b;
 }
}

工厂类OperatorFactory.java

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class OperatorFactory {
 static Map<String, Operation> operationMap = new HashMap<>();

 static {
 operationMap.put("add", new Addition());
 operationMap.put("divide", new Division());
 operationMap.put("multiply", new Multiplication());
 operationMap.put("subtract", new Subtraction());
 operationMap.put("modulo", new Modulo());
 }

 public static Optional<Operation> getOperation(String operation) {
 return Optional.ofNullable(operationMap.get(operation));
 }
}

使用示例

public int calculateUsingFactory(int a, int b, String operator) {
 Operation targetOperation = OperatorFactory
 .getOperation(operator)
 .orElseThrow(() -> new IllegalArgumentException("Invalid Operator"));
 return targetOperation.apply(a, b);
}

3.2 枚举方式重构

枚举实现Operator.java

public enum Operator {
 ADD {
 @Override
 public int apply(int a, int b) {
  return a + b;
 }
 },
 MULTIPLY {
 @Override
 public int apply(int a, int b) {
  return a * b;
 }
 },
 SUBTRACT {
 @Override
 public int apply(int a, int b) {
  return a - b;
 }
 },
 DIVIDE {
 @Override
 public int apply(int a, int b) {
  return a / b;
 }
 },
 MODULO {
 @Override
 public int apply(int a, int b) {
  return a % b;
 }
 };
 public abstract int apply(int a, int b);
}

封装Operator到Calculator.java

public int calculate(int a, int b, Operator operator) {
 return operator.apply(a, b);
}

使用示例

@Test
public void whenCalculateUsingEnumOperator_thenReturnCorrectResult() {
 Calculator calculator = new Calculator();
 int result = calculator.calculate(3, 4, Operator.valueOf("ADD"));
 assertEquals(7, result);
}

3.3 命令模式

抽象的接口

public interface Command {
 Integer execute();
}

实现类

package com.baeldung.reducingIfElse;

public class AddCommand implements Command {

 private int a;
 private int b;

 public AddCommand(int a, int b) {
 this.a = a;
 this.b = b;
 }

 @Override
 public Integer execute() {
 return a + b;
 }
}

其它略
包装

public int calculate(Command command) {
 return command.execute();
}

测试demo

@Test
public void whenCalculateUsingCommand_thenReturnCorrectResult() {
 Calculator calculator = new Calculator();
 int result = calculator.calculate(new AddCommand(3, 7));
 assertEquals(10, result);
}

3.4 规则引擎重构

抽象规则

public interface Rule {
 boolean evaluate(Expression expression);
 Result getResult();
}

实现规则AddRule.java 其它略

public class AddRule implements Rule {
 private int result;
 @Override
 public boolean evaluate(Expression expression) {
 boolean evalResult = false;
 if (expression.getOperator() == Operator.ADD) {
  this.result = expression.getX() + expression.getY();
  evalResult = true;
 }
 return evalResult;
 }
 @Override
 public Result getResult() {
 return new Result(result);
 }
}

其中:返回结果

public class Result {
 int value;

 public Result(int value) {
  this.value = value;
 }

 public int getValue() {
  return value;
 }
}

表达式

public class Expression {
 private Integer x;
 private Integer y;
 private Operator operator;
 public Expression(Integer x, Integer y, Operator operator) {
  this.x = x;
  this.y = y;
  this.operator = operator;
 }
 public Integer getX() {
  return x;
 }
 public Integer getY() {
  return y;
 }
 public Operator getOperator() {
  return operator;
 }
}

规则引擎RuleEngine.java

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class RuleEngine {
 private static List<Rule> rules = new ArrayList<>();
 static {
  rules.add(new AddRule());
 }
 public Result process(Expression expression) {
  Rule rule = rules.stream()
   .filter(r -> r.evaluate(expression))
   .findFirst()
   .orElseThrow(() -> new IllegalArgumentException("Expression does not matches any Rule"));
  return rule.getResult();
 }
}

测试demo

@Test
public void whenNumbersGivenToRuleEngine_thenReturnCorrectResult() {
 Expression expression = new Expression(5, 5, Operator.ADD);
 RuleEngine engine = new RuleEngine();
 Result result = engine.process(expression);
 assertNotNull(result);
 assertEquals(10, result.getValue());
}

4.比较

重构方式 SRP OCP DIP LSP LD CARP
IF/ELSE N N N N N N
工厂方法 Y Y Y Y Y Y
枚举方法 N Y Y Y Y Y
命令模式 Y Y Y Y Y Y
规则引擎 Y Y Y Y Y Y

5.小结

 为了更好的代码重用性,可读性,可靠性,可维护性,我们会尝试将IF/ELSE或者case-switch进行改造,使用工厂方法,枚举方法,命令模式,规则引擎方式不同方法进行尝试,最后使用设计模式的六大原则对代码进行评估。

到此这篇关于java如何消除太多的if else判断的文章就介绍到这了,更多相关java if else 判断内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java利用策略模式优化过多if else代码

    前言 不出意外,这应该是年前最后一次分享,本次来一点实际开发中会用到的小技巧. 比如平时大家是否都会写类似这样的代码: if(a){ //dosomething }else if(b){ //doshomething }else if(c){ //doshomething } else{ ////doshomething } 条件少还好,一旦 else if 过多这里的逻辑将会比较混乱,并很容易出错. 比如这样: 摘自cim中的一个客户端命令的判断条件. 刚开始条件较少,也就没管那么多直接写的:

  • Java中if...else语句使用的学习教程

    if语句 一个if语句包含一个布尔表达式和一条或多条语句. 语法 If语句的用语法如下: if(布尔表达式) {    //如果布尔表达式为true将执行的语句 } 如果布尔表达式的值为true,则执行if语句中的代码块.否则执行If语句块后面的代码. public class Test { public static void main(String args[]){ int x = 10; if( x < 20 ){ System.out.print("这是 if 语句");

  • 详解Java编程中if...else语句的嵌套写法

    if...else if...else语句 if语句后面可以跟elseif-else语句,这种语句可以检测到多种可能的情况. 使用if,else if,else语句的时候,需要注意下面几点: if语句至多有1个else语句,else语句在所有的elseif语句之后. If语句可以有若干个elseif语句,它们必须在else语句之前. 一旦其中一个else if语句检测为true,其他的else if以及else语句都将跳过执行. 语法 if...else语法格式如下: if(布尔表达式 1){

  • Java的Struts框架中的if/else标签使用详解

    这些标签执行可在每一种语言找到的一种基本条件流程. 'If'标签可用于本身或与"Else If''标签和/或单/多'Else'标签,如下图所示: <s:if test="%{false}"> <div>Will Not Be Executed</div> </s:if> <s:elseif test="%{true}"> <div>Will Be Executed</div>

  • java的if else语句入门指南(推荐)

    条件语句,是程序中根据条件是否成立进行选择执行的一类语句,这类语句在实际使用中,难点在于如何准确的抽象条件.例如实现程序登录功能时,如果用户名和密码正确,则进入系统,否则弹出"密码错误"这样的提示框等. 本部分对于条件语句的介绍,重点在于语法讲解和基本的使用,更详细的使用参看后续的综合示例部分. 在Java语言中,条件语句主要有两类语法:if语句和switch语句. 1 .if语句 if关键字中文意思是如果,其细致的语法归纳来说总共有三种:if语句.if-else语句和if-else

  • Java基础教程_判断语句if else

    与三元运算符相比: 好处:可以简化if else 代码 弊端 因为是一个运算符,所以运算玩必须要有一个结果 以上这篇Java基础教程_判断语句if else就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • java如何消除太多的if else判断示例代码

    1.简介 if判断语句是很多编程语言的重要组成部分.但是,若我们最终编写了大量嵌套的if语句,这将使得我们的代码更加复杂和难以维护. 让我们看看能否使用别的方式来做呢. 设计模式是为了更好的代码重用性,可读性,可靠性,可维护性,它有六大原则: 单一职责原则(Single Responsibility Principle,简称SRP):该原则是针对类来说的,即一个类应该只负责一项职责. 开放--封闭原则(The Open-Closed Principle简称OCP):是说软件实体(类.模块.函数等

  • java后台接收app上传的图片的示例代码

    整理文档,搜刮出一个java后台接受app上传的图片的示例代码,稍微整理精简一下做下分享 package com.sujinabo.file; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.UUID; import javax.servlet.S

  • Java生成中间logo的二维码的示例代码

    最近有负责微信开发,对于微信开发的项目,肯定少不了二维码啦,正好有个这样的需求,这对不同的商品生成一个二维码,扫码即刻下单.博主就弄了一个二维码生成的工具类. 弄出来之后,产品经理又说了,中间放上公司的logo是不是好一点?加上吧, 加上公司logo之后,产品经理想了想,每个商品都有个二维码,销售人员有很多个商品二维码,群发给用户,在qq群上,微信群上,怎么知道哪个二维码对应哪个商品的呢?于是决定要加上商品名称.最后商品二维码就成了下面这个模样了(当然啦,这里面的logo并不是博主现职公司的).

  • Java多线程、进度条实现赛马实验的示例代码

    赛马 下周一就要去做java实验了,还记得上一次实验还有一个程序没写完,匆匆交了实验报告的半成品(希望老师没发现www).为了下周一能有更充裕的时间在实验课写代码,我搜了一下我们学校的实验报告.嘿,宁猜怎么着!还真有16年的实验报告.虽然有点不太一样,但题目大多是相同的,于是我就开始写. 这是有关赛马的一个程序,题目如下:编写一个多线程的控制程序,称为赛马程序.创建分别代表两匹马的两个线程,并将它们设置为高低不同的优先级,并以进度条的形式显示赛马过程. 以下是我经过多方学习写出的代码,希望大佬斧

  • Java实现经典角色扮演侦探游戏游戏的示例代码

    目录 前言 游戏背景 主要需求 主要设计 功能截图 代码实现 游戏主界面 主卧 初始化 大厅 总结 前言 游戏背景 百变山庄坐落于太平洋的一座小岛上,山庄主人亦是小岛的主人.这个神秘主人细致周到,邀请函里不仅附着往返港口的机票,港口的邮船也是通往小岛的专线. 初登小岛,恢宏大气的山庄直入眼帘,通过门廊,金碧辉煌的大厅震人心魄. 受邀的侦探们陆续到齐,[侍者]彬彬有礼地站在一旁,他安排你们围坐在一个奇特十边形的桌子旁稍加等待.[侦探指尖]回忆着自己临行前调查的各位名侦探的资料,除了那个神秘的[电话

  • Java实现一个简单的长轮询的示例代码

    目录 分析一下长轮询的实现方式 长轮询与短轮询 配置中心长轮询设计 配置中心长轮询实现 客户端实现 服务端实现 分析一下长轮询的实现方式 现在各大中间件都使用了长轮询的数据交互方式,目前比较流行的例如Nacos的配置中心,RocketMQ Pull(拉模式)消息等,它们都是采用了长轮询方的式实现.就例如Nacos的配置中心,如何做到服务端感知配置变化实时推送给客户端的呢? 长轮询与短轮询 说到长轮询,肯定存在和它相对立的,我们暂且叫它短轮询吧,我们简单介绍一下短轮询: 短轮询也是拉模式.是指不管

  • Java异常退出条件的判断示例代码

    无论是功能性代码还是算法性代码,程序都是一系列流程的合集 既然是流程就分为:一般流程和异常流程: 一般流程保证了基本功能: 异常流程则是对程序稳定性的保证,不能因为一些非法输入,项目就挂了: 注意,布尔表达式的先后顺序,有时不可以交换 if (null == instance || instance.isEmpty()) 0. 常见异常退出条件 参数为空: 表示长度,表示索引的整型为负数,或者超出待索引数组或容器的范围: 1. String 的 startsWith 函数 首先来看 String

  • Java 批量文件压缩导出并下载到本地示例代码

    主要用的是org.apache.tools.zip.ZipOutputStream  这个zip流,这里以Execl为例子. 思路首先把zip流写入到http响应输出流中,再把excel的流写入zip流中(这里可以不用生成文件再打包,只需把execl模板读出写好数据输出到zip流中,并为每次的流设置文件名) 例如:在项目webapp下execl文件中 存在1.xls,2.xls,3.xls文件 1.Controller @RequestMapping(value = "/exportAll&qu

  • JAVA 添加、修改和删除PDF书签的示例代码

    当阅读篇幅较长的PDF文档时,为方便我们再次阅读时快速定位到上一次的阅读位置,可以插入一个书签进行标记:此外,对于文档中已有的书签,我们也可以根据需要进行修改或者删除等操作.本篇文章将通过Java编程来展示如何添加.修改以及删除PDF书签. 工具使用: •Free Spire.Pdf for Java 2.4.4 (免费版) •IntelliJ IDEA Jar包导入: 方式一:首先,从官网获取Free Spire.PDF for Java之后解压,以下是三种在IDEA中快速打开Project

  • Java中Maven项目导出jar包配置的示例代码

    具体代码如下所示: <!-- 第一种打包方式 (maven-jar-plugin), 将依赖包和配置文件放到jar包外 --> <build> <sourceDirectory>src/main/java</sourceDirectory> <resources> <resource> <directory>src/main/resources</directory> <!-- 将<director

随机推荐