如题。代码中嵌套的if/else结构往往导致代码不美观,也不易于理解,那么有哪些技巧可以用来尽可能减少代码中的if/else嵌套呢?
如题。代码中嵌套的if/else结构往往导致代码不美观,也不易于理解,那么有哪些技巧可以用来尽可能减少代码中的if/else嵌套呢?
说一个实际问题:redis能够处理很多的个命令(譬如,get, set,lpush等等),如果你用if,else写(伪代码):
def process(cmd_name, args)
if cmd_name == "get":
# do_action
else if cmd_name == "set":
# do_action
else if ...
很显然这样子写很显然效率低下,而且毎扩展一个命令效率就更加慢,那redis是怎么处理的呢?利用哈希表(伪代码):
redisCommand = [
# 命令名, 命令处理函数
("get", getCommand),
{"set", setCommand)
# ...
]
然后初始化哈希表:dictCmd,其中:
dictCmd.key -> 命令名
dictCmd.val -> 命令处理函数
这个时候处理命令函数变成:
def process(cmd_name, args):
proc = dictCmd.get(cmd_name)
proc(args)
这样就解决了效率问题,扩展一个新命令也非常容易
这其实只是遇到多重if问题的一种解决方法(而且只适合特定场景),有的系统业务复杂,你很难有什么好的方法, 但至少保证代码写的整洁,可读性强
我会用
do {
...
}while(false);
例如
do {
if( test == 1 ) {
break;
}
}
//do anything else ...
还是得看具体情况吧,如果比较简单的判断得到结果确实可以考虑Hash,但是如果是比较复杂的业务逻辑的话也不是Hash可以解决的,所以还是要结合具体情况,也推荐多看些设计模式方面的东西。
https://pypi.python.org/pypi/singledispatch
平时一般用 getattr 写个简单的 dispatch
if a == 'b':
print('a=b')
if c == 'd':
print('c=d')
class dispatch():
def error(self):
print('error')
def __init__(self, func=''):
getattr(self, func, self.error)
def a(self):
print('a=b')
def c(self):
print('c=d')
dispatch('a')
dispatch('b')
对于if中的异常情况,在java中可以用PreConditions包,好像是google的一个包,用法就是:
PreConditions.checkArgument(var, errMsg);
就是说那个变量如果是false就会抛InvalidArgument 异常。
那个包里面提供了非常多的判断各种异常值的静态方法。使用这些方法可以大大的减少分支。(在我们公司,就对代码复杂度有要求,它会作为项目结果的一部分,如果不达标,项目结果就会受影响。)
当然,也不是所有的时候都要抛异常,有时候要对一些情况做一些处理,或者是,程序本身就会有分支,像这种情况,就需要在设计接口、api的时候就充分考虑:
有一些流程的分支,使用多态的方式,由不同的类处理。
有一些业务上相关的数据问题,可以使用自定义的异常,并且在调用的地方进行处理。
如果是同样类型的判断很多地方都要做,那就抽取出来,写一个判断的函数。
最后,还有一点就是,尽量的使用基于协议的方式去编程,不该出现的异常情况,在源头就抛出去,其他地方就不需要再考虑这种情况。
使用多态解决
##### 定义一个接口
interface Operation {
void execute();
}
##### 实现具体的操作类
class OperationA implements Operation {
@Override
public void execute() {
// 实现操作 A 的逻辑
}
}
class OperationB implements Operation {
@Override
public void execute() {
// 实现操作 B 的逻辑
}
}
##### 在调用处使用多态
Operation operation;
if (conditionA) {
operation = new OperationA();
} else if (conditionB) {
operation = new OperationB();
}
operation.execute();
尽量少使用 else,如果在函数中,可以使用
if
+return
,先判断错误条件,然后立马结束函数,防止进入else
分支。刚才去 sof 溜了一圈,发现也有人在问:How to avoid if… else and switch cases
解决方法:
1. switch/case
不解释。
2. hash 表
这个也可以用
switch case
解决,不过推荐的方法是 hash 表:3. 重构,用 OO 里面的继承或者组合
可以重构一下,改成 OO。