日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
if-else判斷語(yǔ)句過多該如何處理?

一、簡(jiǎn)介

if(condition){
doSomeThing();
} else {
doSomeThing();
}

但是當(dāng)過度的使用if-else的時(shí)候,會(huì)對(duì)代碼的可讀性、可擴(kuò)展性造成負(fù)面影響,比如類似下面這個(gè)!

if(condition1){
if(condition2){
if(condition3){
if(condition4){
if(condition5){
if(condition6){
doSomeThing();
}
}
}
}
}
}

如果判斷語(yǔ)句越來越多,后期進(jìn)行項(xiàng)目維護(hù)也會(huì)比較困難,對(duì)于后面接手項(xiàng)目的人來說,會(huì)是一個(gè)很頭疼的問題了。

因此,如何去除掉代碼中過多的if...else語(yǔ)句,反映的是程序員對(duì)軟件重構(gòu)、設(shè)計(jì)模式、面向?qū)ο笤O(shè)計(jì)、架構(gòu)模式、數(shù)據(jù)結(jié)構(gòu)等多方面技術(shù)的綜合運(yùn)用能力。

那問題來了,如何解決代碼中過多的if...else語(yǔ)句呢?下面一起來聊聊有效的幾種解決方案!

二、解決方案

首先,我們編寫一個(gè)簡(jiǎn)單的程序計(jì)算器,代碼如下!

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;
}
return result;
}

以上文為案例,我們一起來看看,可以對(duì)其進(jìn)行改造的幾種方式!

2.1、適時(shí)的 return

如果if里面條件判斷比較單一又互斥的,我們可以在合適的位置直接return,廢除掉else代碼,比如將其改造成如下方式:

public int calculate(int a, int b, String operator) {
if ("add".equals(operator)) {
return a + b;
}
if ("subtract".equals(operator)) {
return a - b;
}
if ("multiply".equals(operator)) {
return a * b;
}
if ("divide".equals(operator)) {
return a / b;
}
return 0;
}

代碼瞬間是不是清晰了很多!

2.2、引入策略模式進(jìn)行改造

但是當(dāng)if判斷邏輯內(nèi)容非常復(fù)雜的時(shí)候,以上的方案就有點(diǎn)不夠優(yōu)雅了,這個(gè)時(shí)候,我們可以將if判斷邏輯獨(dú)立成類來單獨(dú)處理,操作方法如下!

  • 首先,我們定義一個(gè)Operation接口,用于邏輯的計(jì)算
public interface Operation {

/**
* 執(zhí)行計(jì)算
* @param a
* @param b
* @return
*/
int execute(int a, int b);
}
  • 接著,分別將四個(gè)if判斷邏輯獨(dú)立成一個(gè)模塊,來單獨(dú)處理
public class AddOperation implements Operation {

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

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

@Override
public int execute(int a, int b) {
return a * b;
}
}
public class DivOperation implements Operation {

@Override
public int execute(int a, int b) {
return a / b;
}
}
  • 然后,創(chuàng)建一個(gè)工廠類,用于處理客戶端傳入的參數(shù)
public class OperatorFactory {

private static Map operationMap = new HashMap<>();

static {
//初始化實(shí)現(xiàn)類
operationMap.put("add", new AddOperation());
operationMap.put("sub", new SubOperation());
operationMap.put("multi", new MultiOperation());
operationMap.put("div", new DivOperation());
// more operators
}

/**
* 獲取對(duì)應(yīng)的目標(biāo)實(shí)現(xiàn)類
* @param operator
* @return
*/
public static Optional getOperation(String operator){
return Optional.ofNullable(operationMap.get(operator));
}

}
  • 最后,在需要的地方引入方法即可!
public class OperatorTestMain {

public static void main(String[] args) {
//獲取計(jì)算的目標(biāo)實(shí)現(xiàn)類
Operation targetOperation = OperatorFactory
.getOperation("add")
.orElseThrow(() -> new IllegalArgumentException("Invalid Operator"));
int result = targetOperation.execute(1, 2);
System.out.println("result:" + result);
}
}

至此,if...else方法改造完畢!

2.3、引入規(guī)則引擎模式進(jìn)行改造

當(dāng)方法內(nèi)部的if...else越來越多的時(shí)候,我們可以通過規(guī)則引擎模式來消除這種復(fù)雜度,具體實(shí)踐如下!

  • 首先,創(chuàng)建一個(gè)規(guī)則標(biāo)準(zhǔn)接口Rule,并將條件判斷方法進(jìn)行抽象
public interface Rule {

/**
* 檢查是否進(jìn)入規(guī)則計(jì)算
* @param expression
* @return
*/
boolean evaluate(Expression expression);


/**
* 執(zhí)行規(guī)則計(jì)算
* @param expression
* @return
*/
int execute(Expression expression);
}
public class Expression {

private Integer a;

private Integer b;

/**
* 計(jì)算類型
*/
private String operator;

public Expression(Integer a, Integer b, String operator) {
this.a = a;
this.b = b;
this.operator = operator;
}
}
  • 接著,根據(jù)每個(gè)規(guī)則創(chuàng)建不同的計(jì)算實(shí)現(xiàn)類,以AddRule為例
public class AddRule implements Rule {

@Override
public boolean evaluate(Expression expression) {
if ("add".equalsIgnoreCase(expression.getOperator())) {
return true;
}
return false;
}

@Override
public int execute(Expression expression) {
int result = expression.getA() + expression.getB();;
return result;
}
}

然后,創(chuàng)建一個(gè)規(guī)則引擎,用于邏輯的處理

public class RuleEngine {

private static List rules = new ArrayList<>();

static {
rules.add(new AddRule());
//添加其他的規(guī)則計(jì)算實(shí)現(xiàn)類
}


/**
* 執(zhí)行規(guī)則計(jì)算
* @param expression
* @return
*/
public int process(Expression expression){
Rule rule = rules
.stream()
.filter(r -> r.evaluate(expression))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Expression does not matches any Rule"));
return rule.execute(expression);
}

}

最后,在需要的地方引入方法即可!

public class RuleEngineTestMain {

public static void main(String[] args) {
Expression expression = new Expression(1, 2, "add");
RuleEngine engine = new RuleEngine();
int result = engine.process(expression);
System.out.println("result:" + result);
}
}

規(guī)則引擎和策略模式,最大的不同的就是將條件邏輯判斷抽象化,由具體的實(shí)現(xiàn)類來判斷是不是滿足要求,如果滿足要求,就執(zhí)行;否則不執(zhí)行!

三、Spring 集成應(yīng)用

可能有的同學(xué)會(huì)發(fā)出疑問,以上介紹的都是原生的處理辦法,在當(dāng)下處處都集成了Spring框架的項(xiàng)目,我們應(yīng)該如何使用呢?

下面我們以上面提到的《引入策略模式進(jìn)行改造》為例,如果在Spring里面,我們應(yīng)該如何應(yīng)用?

3.1、Spring 策略模式實(shí)現(xiàn)介紹(方案一)

  • 首先,我們還是定義一個(gè)Command接口,用于方法的抽象和統(tǒng)一
public interface Command {

/**
* 命令類型
* @return
*/
String operateType();

/**
* 執(zhí)行
* @param a
* @param b
* @return
*/
Integer execute(int a, int b);

}
  • 接著,編寫四套不同的計(jì)算處理邏輯
@Component
public class AddCommand implements Command {

@Override
public String operateType() {
return "add";
}

@Override
public Integer execute(int a, int b) {
return a + b;
}
}
@Component
public class SubCommand implements Command {

@Override
public String operateType() {
return "subtract";
}

@Override
public Integer execute(int a, int b) {
return a - b;
}
}
@Component
public class MultiCommand implements Command {

@Override
public String operateType() {
return "multiply";
}

@Override
public Integer execute(int a, int b) {
return a * b;
}
}
@Component
public class DivCommand implements Command {

@Override
public String operateType() {
return "divide";
}

@Override
public Integer execute(int a, int b) {
return a / b;
}
}
  • 然后,編寫一個(gè)類似于上文的策略處理類
@Component
public class CalculatorService implements ApplicationContextAware {

private Map commandMap = new ConcurrentHashMap<>();


/**
* 執(zhí)行計(jì)算
* @param operateType
* @param a
* @param b
* @return
*/
public int calculate(String operateType,int a, int b){
Command targetCommand = Optional.ofNullable(commandMap.get(operateType))
.orElseThrow(() -> new IllegalArgumentException("Invalid Operator"));
return targetCommand.execute(a,b);
}


@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map tempMap = applicationContext.getBeansOfType(Command.class);
tempMap.values().forEach(source -> commandMap.put(source.operateType(), source));
}

}
  • 最后,我們只需要在適當(dāng)?shù)奈恢脩?yīng)用即可!
@RunWith(SpringRunner.class)
@SpringBootTest
public class CalculatorServiceTest {

@Autowired
private CalculatorService calculatorService;

@Test
public void test(){
int result = calculatorService.calculate("add", 1,2);
System.out.println("result:" + result);
}
}

3.2、Spring 策略模式實(shí)現(xiàn)介紹(方案二,推薦)

翻查Spring的ioc容器,你會(huì)發(fā)現(xiàn)一個(gè)秘密,當(dāng)一個(gè)接口有多個(gè)實(shí)現(xiàn)類時(shí),Spring會(huì)自動(dòng)將Strategy接口的實(shí)現(xiàn)類注入到這個(gè)Map中,key為bean id,value值則為對(duì)應(yīng)的策略實(shí)現(xiàn)類。

簡(jiǎn)單的說,我們只需要通過@Autowired注入對(duì)象,不需要通過CalculatorService這個(gè)類進(jìn)行單獨(dú)配置,操作方式如下!

  • 首先,編寫一個(gè)CommandFactory工廠類,用于邏輯的處理
@Component
public class CommandFactory {

/**
* Spring會(huì)自動(dòng)將Strategy接口的實(shí)現(xiàn)類注入到這個(gè)Map中,key為bean id,value值則為對(duì)應(yīng)的策略實(shí)現(xiàn)類
*/
@Autowired
private Map commandMap;


/**
* 執(zhí)行計(jì)算
* @param operateType
* @param a
* @param b
* @return
*/
public int calculate(String operateType,int a, int b){
Command targetCommand = Optional.ofNullable(commandMap.get(operateType))
.orElseThrow(() -> new IllegalArgumentException("Invalid Operator"));
return targetCommand.execute(a,b);
}
}
  • 最后,直接在合適的地方使用CommandFactory即可!
@RunWith(SpringRunner.class)
@SpringBootTest
public class CalculatorServiceTest {

@Autowired
private CommandFactory commandFactory;

@Test
public void test(){
int result = commandFactory.calculate("addCommand", 1,2);
System.out.println("result:" + result);
}
}

四、小結(jié)

本文主要圍繞如何解決if...else...過多問題進(jìn)行一些總結(jié)和案例分享,期望能對(duì)大家有所幫助!

五、參考

1、baeldung java-replace-if-statements

2、知乎 - 如何去除代碼中過多的if語(yǔ)句


新聞標(biāo)題:if-else判斷語(yǔ)句過多該如何處理?
網(wǎng)站地址:http://www.dlmjj.cn/article/dhhpgjs.html