我正在阅读本文,并想知道,是否通过用Dictionary或Factory替换它们来摆脱所有switch语句,以便我的项目中根本没有switch语句。
有些东西加起来还不够。
问题是,switch语句是否有任何实际用途,还是我们继续将其替换为字典或工厂方法(当然,在使用工厂方法时,将最少使用switch语句来创建对象)使用工厂...但仅此而已)。
我正在阅读本文,并想知道,是否通过用Dictionary或Factory替换它们来摆脱所有switch语句,以便我的项目中根本没有switch语句。
有些东西加起来还不够。
问题是,switch语句是否有任何实际用途,还是我们继续将其替换为字典或工厂方法(当然,在使用工厂方法时,将最少使用switch语句来创建对象)使用工厂...但仅此而已)。
Answers:
双方switch
陈述和多态性有其用途。请注意,尽管也存在第三个选项(在支持函数指针/ lambda和更高阶函数的语言中):将有问题的标识符映射到处理函数。例如,这在非OO语言的C语言中,以及C *是*,但在Java也是OO *中尚不可用。
在一些过程语言(不具有多态性也不高阶函数)switch
/ if-else
声明是为了解决一类问题的唯一方法。因此,许多习惯了这种思维方式的开发人员switch
甚至继续使用面向对象语言(OO语言),因为多态通常是更好的解决方案。这就是为什么通常建议避免/重构switch
支持多态的语句的原因。
无论如何,最佳解决方案始终取决于大小写。问题是:从长远来看,哪个选项可以为您提供更简洁,更简洁,更可维护的代码?
Switch语句经常会变得笨拙,包含数十种情况,从而使维护变得很困难。由于必须将它们保留在一个函数中,因此该函数可能会变得非常庞大。如果是这种情况,则应考虑将其重构为基于地图和/或多态的解决方案。
如果相同的代码switch
开始在多个地方弹出,那么多态可能是统一所有这些情况并简化代码的最佳选择。尤其是如果预计将来会增加更多案件,则更是如此。每次需要更新的位置越多,出错的可能性就越大。但是,通常情况下,各个案例处理程序是如此简单,或者它们如此之多,或者它们是如此相互关联,以至于将它们重构为完整的多态类层次结构是过大的,或者导致大量重复代码和/或纠结,很难维护类的层次结构。在这种情况下,使用功能/ lambdas可能会更简单(如果您的语言允许)。
但是,如果您switch
在一个地方有一个地方,并且只有少数情况做简单的事情,那么将其保持原样可能是最好的解决方案。
* 我在这里宽松地使用“ OO”一词;我对什么是“真实”或“纯” OO的概念性辩论不感兴趣。
这是我回到恐龙的地方。
Switch语句本身并不是一件坏事,这是由它们所引起的。
最明显的一个是在您的代码中反复多次重复的“相同” switch语句,该语句很糟糕(在那儿这样做,会尽一切努力避免再次出现)-并且这后一种情况您可能能够处理使用多态。嵌套的案例通常也有一些可怕的地方(我曾经有一个绝对的怪物-除了“更好”之外,现在还不确定我现在该如何处理)。
字典作为开关我觉得更具挑战性-从根本上讲,如果您的开关涵盖了100%的情况,但是如果您希望使用默认或不采取任何行动,则开始变得更加有趣。
我认为这是一个避免重复并确保我们在正确的位置组成对象图的问题。
但是,还有一个领悟性(可维护性),并且这两种方法都可以实现-一旦您了解了它的全部工作原理(模式及其实现所在的应用程序)就很容易...但是,如果您来到一行代码中,必须添加一些新内容,然后必须跳到各处来确定需要添加/更改的内容。
尽管我们所有的开发环境都具有强大的功能,但我仍然希望能够理解打印在纸上的代码(就好像它是被打印出来的那样)-您能用手指跟随代码吗?我接受实际上没有,因为今天有很多好的实践,并且出于充分的原因,您不能这样做,但这意味着难以跟上代码的步伐(或者也许我才刚刚老...)
我们通过用Dictionary或Factory替换它们来摆脱所有switch语句,以便我的项目中根本没有switch语句。
不。这样的绝对值很少是一个好主意。
在许多地方,字典/查找/工厂/多态调度将比switch语句提供更好的设计,但是您仍然必须填充字典。在某些情况下,这将掩盖实际发生的事情,并且简单地内联switch语句更易于读取和维护。
看起来这是与语言无关的,穿透式代码最适用于以下switch
语句:
switch(something) {
case 1:
foo();
case 2:
bar();
baz();
break;
case 3:
bang();
default:
bizzap();
break;
}
与等效if
,默认情况非常尴尬。并记住,越深入,条件列表将越长:
if (1 == something) {
foo();
}
if (1 == something || 2 == something) {
bar();
baz();
}
if (3 == something) {
bang();
}
if (1 != something && 2 != something) {
bizzap();
}
(但是,考虑到其他一些答案,我觉得我错过了问题的重点...)
switch
的程度与相同goto
。如果要执行的算法需要适合于结构化编程构造的控制流,则应使用此类构造,但是如果算法不适合此类构造,则使用goto
可能比尝试添加标志或其他控制逻辑来适合其他控制结构更好。 。
区分大小写的switch语句确实有用。函数式编程语言使用一种称为模式匹配的方法,该方法可让您根据输入来不同地定义函数。但是,在面向对象的语言中,可以通过使用多态来更好地达到相同的目标。您只需调用该方法,然后根据对象的实际类型,将执行该方法的相应实现。这就是该想法背后的原因,即switch语句具有代码味道。但是,即使使用OO语言,您也可能会发现它们对于实现抽象工厂模式很有用。
tl; dr-它们很有用,但很多时候您可以做得更好。