这个问题是由我最近开始经常看到的事情引起的,if..else if..else
结构。虽然它很简单并且有它的用途,但它的一些东西一遍又一遍地告诉我,它可以被更细粒度、更优雅并且通常更容易保持最新的东西所取代。
尽可能具体,这就是我的意思:
if (i == 1) {
doOne();
} else if (i == 2) {
doTwo();
} else if (i == 3) {
doThree();
} else {
doNone();
}
我可以想到两种简单的方法来重写它,或者通过三元(这只是编写相同结构的另一种方法):
(i == 1) ? doOne() :
(i == 2) ? doTwo() :
(i == 3) ? doThree() : doNone();
或使用 Map(在 Java 中,我认为也在 C# 中)或 Dictionary 或任何其他 K/V 结构,如下所示:
public interface IFunctor() {
void call();
}
public class OneFunctor implemets IFunctor() {
void call() {
ref.doOne();
}
}
/* etc. */
Map<Integer, IFunctor> methods = new HashMap<Integer, IFunctor>();
methods.put(1, new OneFunctor());
methods.put(2, new TwoFunctor());
methods.put(3, new ThreeFunctor());
/* .. */
(methods.get(i) != null) ? methods.get(i).call() : doNone();
事实上,上面的 Map 方法是我上次所做的,但现在我无法停止思考,对于这个确切的问题,一般必须有更好的替代方法。
那么,还有哪些其他(而且很可能是更好的)方法来替代 if..else if..else,您最喜欢哪一种?
你的想法就在这条线下面!
好的,这是your想法:
首先,最受欢迎的答案是 switch 语句,如下所示:
switch (i) {
case 1: doOne(); break;
case 2: doTwo(); break;
case 3: doThree(); break;
default: doNone(); break;
}
这仅适用于可在开关中使用的值,这至少在 Java 中是一个相当大的限制因素。当然,对于简单的情况来说是可以接受的。
您似乎建议的另一种也许更奇特的方法是使用多态性来实现。 CMS 链接的 Youtube 讲座非常精彩,请在这里观看:《整洁代码讲座——继承、多态性和测试》 http://www.youtube.com/watch?v=4F72VULWFvc据我了解,这将转化为这样的内容:
public interface Doer {
void do();
}
public class OneDoer implements Doer {
public void do() {
doOne();
}
}
/* etc. */
/* some method of dependency injection like Factory: */
public class DoerFactory() {
public static Doer getDoer(int i) {
switch (i) {
case 1: return new OneDoer();
case 2: return new TwoDoer();
case 3: return new ThreeDoer();
default: return new NoneDoer();
}
}
}
/* in actual code */
Doer operation = DoerFactory.getDoer(i);
operation.do();
Google 演讲中有两个有趣的观点:
- 使用空对象而不是返回空值(并且请仅抛出运行时异常)
- 尝试编写一个没有 if:s 的小项目。
另外,我认为值得一提的一个帖子是 CDR,他向我们提供了他的不正当习惯,虽然不建议使用,但看起来非常有趣。
谢谢大家的回答(到目前为止),我想我今天可能学到了一些东西!