ITPub博客

首页 > > > java如何消除太多的if else判断?

java如何消除太多的if else判断?

作者:longmanma 时间:2019-12-31 09:26:38 0 删除 编辑

1.简介

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

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

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

1)单一职责原则(Single Responsibility Principle,简称SRP):该原则是针对类来说的,即一个类应该只负责一项职责.

2)开放--封闭原则(The Open-Closed Principle简称OCP):是说软件实体(类、模块、函数等等)应该可以扩展,但是不可以修改。

3)依赖倒转原则(Dependence Inversion Principle :针对接口编程,不要对实现编程

4)里氏代换原则(Liskov Substitution Principle,简称LSP):里氏代换原则,子类型必须能够替换掉他们的父类型

5)迪米特法则(Law of Demeter):如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用

6)合成/聚合复用原则(Composition/Aggregation Principle],简称CARP):尽量使用合成/聚合,尽量不使用类继承。合成聚合是“has  a”的关系,而继承是“is  a”的关系。

2.示例

if..else

publicintcalculate(inta,int b, String operator) {

intresult = Integer.MIN_VALUE;

if("add".equals(operator)) {

result = a + b;

} elseif("multiply".equals(operator)) {

result = a * b;

} elseif("divide".equals(operator)) {

result = a / b;

} elseif("subtract".equals(operator)) {

result = a - b;

} elseif("modulo".equals(operator)) {

result = a % b;

}

return result;

}

case-switch

publicintcalculateUsingSwitch(inta,int b, String operator) {

intresult = 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

publicinterface Operation {

intapply(inta,int b);

}

加法实现Addition.java:

publicclassAdditionimplements Operation {

@Override

publicintapply(inta,int b) {

returna + b;

}

}

减法实现Subtraction.java

publicclassSubtractionimplements Operation {

@Override publicintapply(inta,int b) {

returna - b;

}

}

乘法实现Multiplication.java

publicclassMultiplicationimplements Operation {

@Override publicintapply(inta,int b) {

returna*b;

}

}

除法实现Division.java

publicclassDivisionimplements Operation {

@Override publicintapply(inta,int b) {

returna / b;

}

}

求余实现Modulo.java

publicclassModuloimplements Operation {

@Override publicintapply(inta,int b) {

returna % b;

}

}

工厂类OperatorFactory.java

import java.util.HashMap;import java.util.Map;import java.util.Optional;publicclass OperatorFactory {

staticMap operationMap =newHashMap ();

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());

}

publicstaticOptional getOperation(String operation) {

return Optional.ofNullable(operationMap.get(operation));

}

}

使用示例

publicintcalculateUsingFactory(inta,int b, String operator) {

Operation targetOperation = OperatorFactory

.getOperation(operator)

.orElseThrow(() ->newIllegalArgumentException("Invalid Operator"));

return targetOperation.apply(a, b);

}

 

3.2 枚举方式重构

枚举实现Operator.java

publicenum Operator {

ADD {

@Override

publicintapply(inta,int b) {

returna + b;

}

},

MULTIPLY {

@Override

publicintapply(inta,int b) {

returna * b;

}

},

SUBTRACT {

@Override

publicintapply(inta,int b) {

returna - b;

}

},

DIVIDE {

@Override

publicintapply(inta,int b) {

returna / b;

}

},

MODULO {

@Override

publicintapply(inta,int b) {

returna % b;

}

};

publicabstractintapply(inta,int b);

}

封装Operator到Calculator.java

publicintcalculate(inta,int b, Operator operator) {

return operator.apply(a, b);

}

使用示例

@Testpublicvoid whenCalculateUsingEnumOperator_thenReturnCorrectResult() {

Calculator calculator =new Calculator();

intresult = calculator.calculate(3, 4, Operator.valueOf("ADD"));

assertEquals(7, result);

}

 

3.3 命令模式

抽象的接口

publicinterface Command {

Integer execute();

}

实现类

package com.baeldung.reducingIfElse;publicclassAddCommandimplements Command {

privateint a;

privateint b;

publicAddCommand(inta,int b) {

this.a = a;

this.b = b;

}

@Override

public Integer execute() {

returna + b;

}

}

其它略

包装

publicint calculate(Command command) {

return command.execute();

}

测试demo

@Testpublicvoid whenCalculateUsingCommand_thenReturnCorrectResult() {

Calculator calculator =new Calculator();

intresult = calculator.calculate(newAddCommand(3, 7));

assertEquals(10, result);

}

 

4.规则引擎重构

抽象规则

publicinterface Rule {

boolean evaluate(Expression expression);

Result getResult();

}

实现规则AddRule.java 其它略

publicclassAddRuleimplements Rule {

privateint result;

@Override

publicboolean evaluate(Expression expression) {

booleanevalResult =false;

if(expression.getOperator() == Operator.ADD) {

this.result = expression.getX() + expression.getY();

evalResult =true;

}

return evalResult;

}

@Override

public Result getResult() {

returnnew Result(result);

}

}

 

其中:返回结果

publicclass Result {

int value;

publicResult(int value) {

this.value = value;

}

publicint getValue() {

return value;

}

}

表达式

publicclass 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;publicclass RuleEngine {

privatestaticList rules =newArrayList ();

static {

rules.add(new AddRule());

}

public Result process(Expression expression) {

Rule rule = rules.stream()

.filter(r -> r.evaluate(expression))

.findFirst()

.orElseThrow(() ->newIllegalArgumentException("Expression does not matches any Rule"));

return rule.getResult();

}

}

测试demo

@Testpublicvoid whenNumbersGivenToRuleEngine_thenReturnCorrectResult() {

Expression expression =newExpression(5, 5, Operator.ADD);

RuleEngine engine =new RuleEngine();

Result result = engine.process(expression);

assertNotNull(result);

assertEquals(10, result.getValue());

}

4.比较

重构方式SRPOCPDIPLSPLDCARP

IF/ELSENNNNNN

工厂方法YYYYYY

枚举方法NYYYYY

命令模式YYYYYY

规则引擎YYYYYY

 

5.小结

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

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

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

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

1)单一职责原则(Single Responsibility Principle,简称SRP):该原则是针对类来说的,即一个类应该只负责一项职责.

2)开放--封闭原则(The Open-Closed Principle简称OCP):是说软件实体(类、模块、函数等等)应该可以扩展,但是不可以修改。

3)依赖倒转原则(Dependence Inversion Principle :针对接口编程,不要对实现编程

4)里氏代换原则(Liskov Substitution Principle,简称LSP):里氏代换原则,子类型必须能够替换掉他们的父类型

5)迪米特法则(Law of Demeter):如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用

6)合成/聚合复用原则(Composition/Aggregation Principle],简称CARP):尽量使用合成/聚合,尽量不使用类继承。合成聚合是“has  a”的关系,而继承是“is  a”的关系。

2.示例

if..else

publicintcalculate(inta,int b, String operator) {

intresult = Integer.MIN_VALUE;

if("add".equals(operator)) {

result = a + b;

} elseif("multiply".equals(operator)) {

result = a * b;

} elseif("divide".equals(operator)) {

result = a / b;

} elseif("subtract".equals(operator)) {

result = a - b;

} elseif("modulo".equals(operator)) {

result = a % b;

}

return result;

}

case-switch

publicintcalculateUsingSwitch(inta,int b, String operator) {

intresult = 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

publicinterface Operation {

intapply(inta,int b);

}

加法实现Addition.java:

publicclassAdditionimplements Operation {

@Override

publicintapply(inta,int b) {

returna + b;

}

}

减法实现Subtraction.java

publicclassSubtractionimplements Operation {

@Override publicintapply(inta,int b) {

returna - b;

}

}

乘法实现Multiplication.java

publicclassMultiplicationimplements Operation {

@Override publicintapply(inta,int b) {

returna*b;

}

}

除法实现Division.java

publicclassDivisionimplements Operation {

@Override publicintapply(inta,int b) {

returna / b;

}

}

求余实现Modulo.java

publicclassModuloimplements Operation {

@Override publicintapply(inta,int b) {

returna % b;

}

}

工厂类OperatorFactory.java

import java.util.HashMap;import java.util.Map;import java.util.Optional;publicclass OperatorFactory {

staticMap operationMap =newHashMap ();

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());

}

publicstaticOptional getOperation(String operation) {

return Optional.ofNullable(operationMap.get(operation));

}

}

使用示例

publicintcalculateUsingFactory(inta,int b, String operator) {

Operation targetOperation = OperatorFactory

.getOperation(operator)

.orElseThrow(() ->newIllegalArgumentException("Invalid Operator"));

return targetOperation.apply(a, b);

}

 

3.2 枚举方式重构

枚举实现Operator.java

publicenum Operator {

ADD {

@Override

publicintapply(inta,int b) {

returna + b;

}

},

MULTIPLY {

@Override

publicintapply(inta,int b) {

returna * b;

}

},

SUBTRACT {

@Override

publicintapply(inta,int b) {

returna - b;

}

},

DIVIDE {

@Override

publicintapply(inta,int b) {

returna / b;

}

},

MODULO {

@Override

publicintapply(inta,int b) {

returna % b;

}

};

publicabstractintapply(inta,int b);

}

封装Operator到Calculator.java

publicintcalculate(inta,int b, Operator operator) {

return operator.apply(a, b);

}

使用示例

@Testpublicvoid whenCalculateUsingEnumOperator_thenReturnCorrectResult() {

Calculator calculator =new Calculator();

intresult = calculator.calculate(3, 4, Operator.valueOf("ADD"));

assertEquals(7, result);

}

 

3.3 命令模式

抽象的接口

publicinterface Command {

Integer execute();

}

实现类

package com.baeldung.reducingIfElse;publicclassAddCommandimplements Command {

privateint a;

privateint b;

publicAddCommand(inta,int b) {

this.a = a;

this.b = b;

}

@Override

public Integer execute() {

returna + b;

}

}

其它略

包装

publicint calculate(Command command) {

return command.execute();

}

测试demo

@Testpublicvoid whenCalculateUsingCommand_thenReturnCorrectResult() {

Calculator calculator =new Calculator();

intresult = calculator.calculate(newAddCommand(3, 7));

assertEquals(10, result);

}

 

4.规则引擎重构

抽象规则

publicinterface Rule {

boolean evaluate(Expression expression);

Result getResult();

}

实现规则AddRule.java 其它略

publicclassAddRuleimplements Rule {

privateint result;

@Override

publicboolean evaluate(Expression expression) {

booleanevalResult =false;

if(expression.getOperator() == Operator.ADD) {

this.result = expression.getX() + expression.getY();

evalResult =true;

}

return evalResult;

}

@Override

public Result getResult() {

returnnew Result(result);

}

}

 

其中:返回结果

publicclass Result {

int value;

publicResult(int value) {

this.value = value;

}

publicint getValue() {

return value;

}

}

表达式

publicclass 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;publicclass RuleEngine {

privatestaticList rules =newArrayList ();

static {

rules.add(new AddRule());

}

public Result process(Expression expression) {

Rule rule = rules.stream()

.filter(r -> r.evaluate(expression))

.findFirst()

.orElseThrow(() ->newIllegalArgumentException("Expression does not matches any Rule"));

return rule.getResult();

}

}

测试demo

@Testpublicvoid whenNumbersGivenToRuleEngine_thenReturnCorrectResult() {

Expression expression =newExpression(5, 5, Operator.ADD);

RuleEngine engine =new RuleEngine();

Result result = engine.process(expression);

assertNotNull(result);

assertEquals(10, result.getValue());

}

4.比较

重构方式SRPOCPDIPLSPLDCARP

IF/ELSENNNNNN

工厂方法YYYYYY

枚举方法NYYYYY

命令模式YYYYYY

规则引擎YYYYYY

 

5.小结

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

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2730/viewspace-3121119/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-12-18

  • 博文量
    492
  • 访问量
    11996