什么是最好的方式来替换或替代if..else如果程序中的树? [英] What is the best way to replace or substitute if..else if..else trees in programs?

查看:341
本文介绍了什么是最好的方式来替换或替代if..else如果程序中的树?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是由于我最近开始经常看到的东西, if..else if..else 结构的动机。虽然它很简单,有其用途,但有关它的信息一直告诉我,它可以替代更细腻,优雅,通常更容易保持最新的东西。

This question is motivated by something I've lately started to see a bit too often, the if..else if..else structure. While it's simple and has its uses, something about it keeps telling me again and again that it could be substituted with something that's more fine-grained, elegant and just generally easier to keep up-to-date.

为了尽可能具体,这就是我的意思:

To be as specific as possible, this is what I mean:

if (i == 1) {
    doOne();
} else if (i == 2) {
    doTwo();
} else if (i == 3) {
    doThree();
} else {
    doNone();
}

我可以想到两种简单的方式来重写,无论是通过三元是另一种编写相同结构的方式):

I can think of two simple ways to rewrite that, either by ternary (which is just another way of writing the same structure):

(i == 1) ? doOne() : 
(i == 2) ? doTwo() :
(i == 3) ? doThree() : doNone();



<结构如下:

or using Map (in Java and I think in C# too) or Dictionary or any other K/V structure like this:

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方法是我最后一次做的,但现在我不能停止认为在这个确切的问题上必须有更好的替代方案。

In fact the Map method above is what I ended up doing last time but now I can't stop thinking that there has to be better alternatives in general for this exact issue.

所以,哪些其他 - 最有可能更好的方法来替换if..else如果。

So, which other -and most likely better- ways to replace the if..else if..else are out there and which one is your favorite?

好的,这里是您的想法:

首先,最流行的答案是switch语句,如下所示:

First, most popular answer was switch statement, like so:

switch (i) {
    case 1:  doOne(); break;
    case 2:  doTwo(); break;
    case 3:  doThree(); break;
    default: doNone(); break;
}

只适用于可用于交换机的值,至少在Java是一个很大的限制因素。自然而然,对于简单的案例,可以接受。

That only works for values which can be used in switches, which at least in Java is quite a limiting a factor. Acceptable for simple cases though, naturally.

您似乎建议使用的另一种可能有点好处就是使用多态。由CMS链接的Youtube讲座是一个很好的手表,请看这里:清洁代码谈话 - 继承,多态性和测试据我所知,这将转换成如下所示:

The other and perhaps a bit fancier way you seem to sugges is to do it using polymorphism. The Youtube lecture linked by CMS is an excellent watch, go see it here: "The Clean Code Talks -- Inheritance, Polymorphism, & Testing" As far as I understood, this would translate to something like this:

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 Talk中的两个有趣的点:

Two interesting points from the Google talk:


  • 使用Null对象而不是返回null(并且只抛出运行时异常)

  • 尝试写一个小项目,而不需要:s。

另外还有一个在我看来值得一提的帖子是CDR,他们向我们提供了他的不良习惯,而不推荐使用,这只是非常有趣

Also in addition one post worth mentioning in my opinion is CDR who provided his perverse habits with us and while not recommended to use, it's just very interesting to look at.

感谢大家的答案(到目前为止),我想我今天可能会学到一些东西!

Thank you all for the answers (so far), I think I might have learned something today!

推荐答案

这些结构通常可以被多态代替。这将给你更短和更少的代码。

These constructs can often be replaced by polymorphism. This will give you shorter and less brittle code.

这篇关于什么是最好的方式来替换或替代if..else如果程序中的树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆