在 Java 语言中有一堆 instanceof 的 else-if 语句,该如何重构才能使代码更加美观并且效率更快??

2016-04-12 09:17:02 +08:00
 XiaST

在写 Java 程序的时候遇到了如下格式的逻辑: if (s instanceof FunctionDef) { ... } else if (s instanceof ClassDef) { ... } else if (s instanceof Return) { ... } ...

对于这种代码该如何重构才能使得程序看上去更加简洁并且高效?

6561 次点击
所在节点    Java
20 条回复
knightdf
2016-04-12 09:23:15 +08:00
换成 Scala 用 match case, 哈哈
ahmiao
2016-04-12 09:24:15 +08:00
统一接口+子类化?
wanghaa
2016-04-12 09:31:49 +08:00
gqlxj1987
2016-04-12 09:34:01 +08:00
工厂+策略模式
zhuangzhuang1988
2016-04-12 09:40:53 +08:00
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

abstract class Validate {
abstract boolean validate(Object obj);
abstract void process(Object val);
}

class A {

}
class B {

}

class AValidate extends Validate {

@Override
boolean validate(Object obj) {
return obj instanceof A;
}

@Override
void process(Object val) {
A a = (A)val;
// ...
}
}

class BValidate extends Validate {
@Override
boolean validate(Object obj) {
return obj instanceof B;
}
@Override
void process(Object val) {
B a = (B)val;
// ...
}
}

public class Main {
public static void main(String[] args) {
Object a = new A();
Validate[] validates = {
new AValidate(),
new BValidate()
};
for(Validate v: validates ){
if(v.validate(a)){
v.process(a);
break;
}
}
}
}
试试下.
beanlam
2016-04-12 09:41:52 +08:00
用多态,一个分支对应一个实现。这种方法对于有大量分支的情况可能不适用,因为要写大量的类。
另外一种模式可以参考《代码大全》第十八章提到的“表驱动模式”。
SpicyCat
2016-04-12 09:42:57 +08:00
@ahmiao 同意用接口加子类。 FunctionDef, ClassDef 和 Return 可以实现同一个接口或者继承同一个父类,假设父类叫 Father, 方法名叫 doSomething(), 然后那三个子类各自实现 doSomething(). 这样代码里只需要调用 Father#doSomething 就可以了。
levn
2016-04-12 09:47:56 +08:00
改成一种更加复杂难懂的方式
cxshun
2016-04-12 09:49:57 +08:00
面向接口编程,多态就是这个时候用的。
fwrq41251
2016-04-12 09:54:58 +08:00
访问者模式。
或者用 java8 ,有个叫 javaslang 的类库,有用于类型匹配的类。
SoloCompany
2016-04-12 09:56:13 +08:00
首选是多态
不适合多态的可以试一下 Kotlin 用 case when 来代替了 if else 而已也没啥区别
wanttofly
2016-04-12 10:56:59 +08:00
谢谢回答,最近正好有这方面的修改。
hrong
2016-04-12 11:07:10 +08:00
@beanlam 表驱动模式对取值还好,要取函数指针就不合适了, JAVA 不支持函数指针,不知道 java8 能否实现
beanlam
2016-04-12 12:21:34 +08:00
@hrong 是的, jdk1.7 我一般都用匿名内部类作为 value ,伪装函数。
zhuangzhuang1988
2016-04-12 13:37:21 +08:00
或者看这种解决方式, 当然有点难 `functional-programming-in-scala` 作者写的 http://blog.higher-order.com/blog/2009/08/21/structural-pattern-matching-in-java/
kaneg
2016-04-12 14:02:39 +08:00
这不就是多态要解决的问题吗
twoyuan
2016-04-12 14:15:25 +08:00
我现在是建一个 Map<Class, Callback> map ,用的时候 map.get(object.class)。不过第一次创建时会慢点
Jaylee
2016-04-12 14:18:29 +08:00
这应该是用多态吧
laibin
2016-04-12 14:24:26 +08:00
访问者模式。
haolly
2016-04-12 14:28:54 +08:00
重構裏面說過,當你看到大量 switch 或者 if-else 的時候,這表示你應該用多態了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/270346

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX