Esk*_*sko 34 language-agnostic design-patterns
这个问题的动机是我最近开始看到的有点过于if..else if..else结构的东西.虽然它很简单并且有其用途,但它的一些东西不断告诉我它可以用更精细,优雅和通常更容易保持最新的东西代替.
为了尽可能具体,这就是我的意思:
if (i == 1) {
doOne();
} else if (i == 2) {
doTwo();
} else if (i == 3) {
doThree();
} else {
doNone();
}
Run Code Online (Sandbox Code Playgroud)
我可以想到两种简单的方法来重写它,或者通过三元(这只是编写相同结构的另一种方式):
(i == 1) ? doOne() :
(i == 2) ? doTwo() :
(i == 3) ? doThree() : doNone();
Run Code Online (Sandbox Code Playgroud)
或使用Map(在Java中,我认为在C#中)或字典或任何其他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();
Run Code Online (Sandbox Code Playgroud)
事实上,上面的Map方法是我最后一次做的,但是现在我不能不再想到这个问题必须有更好的替代方案.
那么,哪个其他 - 并且最有可能更好的方法来替换if..else if..else在那里,哪一个是你最喜欢的?
好的,这是你的想法:
首先,最流行的答案是switch语句,如下所示:
switch (i) {
case 1: doOne(); break;
case 2: doTwo(); break;
case 3: doThree(); break;
default: doNone(); break;
}
Run Code Online (Sandbox Code Playgroud)
这仅适用于可用于交换机的值,至少在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();
Run Code Online (Sandbox Code Playgroud)
谷歌谈话的两个有趣点:
此外,在我看来,值得一提的一个帖子是CDR,他提供了我不正常的习惯,虽然不建议使用,但是看起来非常有趣.
谢谢大家的答案(到目前为止),我想我今天可能已经学到了什么!
And*_*nan 11
一个开关声明:
switch(i)
{
case 1:
doOne();
break;
case 2:
doTwo();
break;
case 3:
doThree();
break;
default:
doNone();
break;
}
Run Code Online (Sandbox Code Playgroud)
CMS*_*CMS 11
在面向对象的语言中,通常使用多态来替换if.
我喜欢这个涵盖主题的Google Clean Code Talk:
抽象
你的代码是否包含if语句?切换声明?你在不同的地方有相同的开关声明吗?当您进行更改时,您发现自己在几个地方进行相同的更改if/switch?你有没有忘记一个?
本演讲将讨论使用面向对象技术去除许多条件的方法.结果是更清晰,更紧凑,设计更好的代码,更易于测试,理解和维护.
根据你所使用的东西的类型,考虑创建一个对象的层次结构并使用多态.像这样:
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}
};
Run Code Online (Sandbox Code Playgroud)
然后在你的代码中只需调用p-> Foo(),就会发生正确的事情.