开关语句(Switch Case)总是错误的吗?

12

除了简单性之外,是否有switch(case)是更好的设计选择(例如策略或类似模式)的情况...


1
在Perl中,它是 given / when - Brad Gilbert
8个回答

28

在测试基本类型的值(如整数或字符)时,请使用 Switches。

在不同类型之间进行选择时,请使用 polymorphism。

例如: 测试用户输入的字符是否为“a”、“b”或“c”应使用 switch。 测试您正在处理的对象是 Dog 还是 Cat 应使用多态分派。

在许多语言中,如果您有更复杂的值,可能无法使用 Switch。


1
开关总是涉及行为类型,因为它们正在选择行为。值没有行为。用户没有输入'a'、'b'或'c',他们做出了选择,程序的行为取决于该选择的类型。他们按下的键只是该类型的临时引用,就像指针可以引用类一样。多态性将是更清晰的建模方式。 - Mike A

18

首先,简单通常是一个很好的设计选择。

我从来没有理解过反对switch/case的偏见。是的,它可能会被滥用,但是几乎每种其他编程结构也可能被滥用。

在类型上使用switch通常是错误的,可能应该被多态所取代。对其他事物进行switch通常是可以的。


1
开关选择行为 - 因此暗示涉及行为类型,即无论打开什么都“是”或“有”一组可区分的类型,否则就无法使用开关。因此,我们总是打开一种类型,并且我同意您的观点,即打开一种类型是“错误”的(因为很难维护和重用行为)。 - Mike A

5

首先,可读性。


有意义的命名类和有意义的命名方法对其他程序员来说比匿名块更易读,因为匿名块需要重复使用,而它们嵌套在switch语句或其他任何地方。if语句也同样糟糕。 - Mike A

5

是的,绝对可以这样做。很多时候,你的开关只与你整体逻辑的一小部分相关,为此创建全新的类可能会是一个错误。

例如,假设你有一个单词数据库,用户输入另一个单词,你想在数据库中查找该单词,但要包括可能的复数形式。你可以编写类似以下的代码(C++):


vector<string> possible_forms;
possible_forms.push_back(word);
char last_letter = word[word.size() - 1];
switch (last_letter) {
  case 's':
  case 'i':
  case 'z':
    possible_forms.push_back(word + "es");
    break;
  case 'y':
    possible_forms.push_back(word.substr(0, word.size() - 1) + "ies");
    break;
  default:
    possible_forms.push_back(word + "s");
}

使用策略来做这件事情可能有些过头。


“person”、“sheep”或者已经是复数的单词怎么办?复数形式是给定单词类型的一部分。有了多态性,我们没问题,可以稍后添加这些内容而不需要更改代码。使用switch语句,您必须修改和扩展代码。英语有很多规则,如果上面的switch语句的“次要影响”变成了“主要维护问题”,那么可能会有1000多行代码。我曾经看到别人的代码中有单个switch语句长达近3000行。因此,不,总有比使用switch更好的选择。 - Mike A
5
这段代码目前只有15行。如果别人将它改写成1000多行的单个switch语句,那就是他们的问题,而不是最初switch语句的问题。 - lacker

1

通常情况下,只要你在一个地方只有一个开关,那就没问题。但是当你有多个(或者很多)时,就该考虑其他选择了。


0

可以使用 switch 创建“策略”。

这可能是起点,然后让多态性发挥作用。

其他需要在灵活性成本上获得额外速度的情况也值得考虑。


-1
不是的,switch语句可能只在简单情况下是一个好的设计选择。

一旦你超越了简单的情况,switch语句变得非常痛苦,需要不断更新和维护。这也是设计模式产生的部分原因。


-4

我认为switch语句始终是错误的:

case语句体是代码,代表着行为,因此,case中的值('value')具有行为类型,因此,多态性会是更好的选择。

这意味着值实际上是类型,例如数字1是一切等于1的东西的类型。我们只需要将“1”的特质映射到我们特定情况下的行为中,就可以得到所有其他类型的多态性(这是一个好事情)。

在某些语言中,这样做很容易,但不幸的是,大多数常用的语言都非常糟糕,所以最少阻力的路线是错误的选择,人们最终只能编写switch或if语句(本质相同)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接