当前位置:  开发笔记 > 编程语言 > 正文

在程序中替换或替换if..else if..else树的最佳方法是什么?

如何解决《在程序中替换或替换if..elseif..else树的最佳方法是什么?》经验,为你挑选了5个好方法。

这个问题的动机是我最近开始看到的有点过于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#中)或字典或任何其他K/V结构,如下所示:

public interface IFunctor() {
    void call();
}

public class OneFunctor implemets IFunctor() {
    void call() {
        ref.doOne();
    }
}

/* etc. */    

Map methods = new HashMap();
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在那里,哪一个是你最喜欢的?

你的想法低于这条线!


好的,这是你的想法:

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

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

这仅适用于可用于交换机的值,至少在Java中这是一个非常有限的因素.但是,对于简单的情况,自然可以接受.

你似乎建议的另一个也许有点更有趣的方法是使用多态.由CMS联系的Youtube讲座是一款出色的手表,请看这里:"清洁代码会谈 - 继承,多态,和测试"据我所知,这将转化为这样的事情:

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();

谷歌谈话的两个有趣点:

使用Null对象而不是返回空值(请仅抛出运行时异常)

尝试编写一个没有if:s的小项目.

此外,在我看来,值得一提的一个帖子是CDR,他提供了我不正常的习惯,虽然不建议使用,但是看起来非常有趣.

谢谢大家的答案(到目前为止),我想我今天可能已经学到了什么!



1> Brian Rasmus..:

这些结构通常可以被多态性取代.这将为您提供更短,更简单的代码.



2> Andrew Kenna..:

一个开关声明:

switch(i)
{
  case 1:
    doOne();
    break;

  case 2:
    doTwo();
    break;

  case 3:
    doThree();
    break;

  default:
    doNone();
    break;
}



3> CMS..:

在面向对象的语言中,通常使用多态来替换if.

我喜欢这个涵盖主题的Google Clean Code Talk:

清洁代码会谈 - 继承,多态和测试

抽象

你的代码是否包含if语句?切换声明?你在不同的地方有相同的开关声明吗?当您进行更改时,您发现自己在几个地方进行相同的更改if/switch?你有没有忘记一个?

本演讲将讨论使用面向对象技术去除许多条件的方法.结果是更清晰,更紧凑,设计更好的代码,更易于测试,理解和维护.



4> 小智..:

这个问题有两个部分.

如何根据价值发货?使用switch语句.它最清楚地显示您的意图.

什么时候根据价值发货?每个值只在一个位置:创建一个知道如何为值提供预期行为的多态对象.



5> Steve Rowe..:

根据你所使用的东西的类型,考虑创建一个对象的层次结构并使用多态.像这样:

class iBase
{
   virtual void Foo() = 0;
};

class SpecialCase1 : public iBase
{
   void Foo () {do your magic here}
};

class SpecialCase2 : public iBase
{
   void Foo () {do other magic here}
};

然后在你的代码中只需调用p-> Foo(),就会发生正确的事情.

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有