切换语句不好?

Hon*_*gbo 32 oop design-patterns coding-style switch-statement

我最近了解到开关语句在OOP中很糟糕,特别是罗伯特·马丁的"清洁代码"(第37-39页).

但请考虑这个场景:我正在编写一个游戏服务器,接收来自客户端的消息,其中包含一个表示玩家行为的整数,例如移动,攻击,挑选项目......等等,将有超过30种不同的动作.当我编写代码来处理这些消息时,没有想到我想到的解决方案,它将不得不在某处使用switch.如果不切换语句,我应该使用什么模式?

Tob*_*oby 31

开关就像任何其他控制结构一样.有些地方是最好/最干净的解决方案,还有更多地方是完全不合适的地方.它比其他控制结构更容易被滥用.

在OO设计中,通常认为在像您这样的情况下使用从公共消息类继承的不同消息类型/类,然后使用重载方法来"自动"区分不同类型.

在像你这样的情况下,你可以使用映射到你的动作代码的枚举,然后将一个属性附加到每个枚举值,这将允许你使用泛型或类型构建来构建不同的Action子类对象,以便重载方法将工作.

但那是一个真正的痛苦.

评估是否存在设计选项,例如在您的解决方案中可行的枚举.如果没有,只需使用开关.

  • 我猜你的意思是动态多态而不是静态多态(*重载方法*) (2认同)

The*_*aul 18

'坏'切换语句通常是那些切换对象类型(或者可能是另一种设计中的对象类型的东西).换句话说,硬编码可能更好地处理多态的东西.其他类型的switch语句可能没问题

您将需要一个switch语句,但只需要一个.当您收到消息时,调用Factory对象以返回相应Message子类的对象(Move,Attack等),然后调用message-> doit()方法来完成工作.

这意味着如果添加更多消息类型,则只需更改工厂对象.


Ode*_*ded 17

Strategy想到了这种模式.

策略模式旨在提供定义算法族的方法,将每个算法封装为对象,并使它们可互换.策略模式允许算法独立于使用它们的客户端.

在这种情况下,"算法族"是您不同的行为.


至于switch语句 - 在"清洁代码"中,Robert Martin说他试图将自己限制为每种类型的一个 switch语句.完全没有消除它们.

原因是switch语句不符合OCP.


小智 5

我将消息放入数组中,然后将该项目与解决方案键相匹配以显示消息。


Jam*_*mes 5

我不买。这些 OOP 狂热者似乎拥有拥有无限 RAM 和惊人性能的机器。显然,使用无限的 RAM,您不必担心 RAM 碎片以及连续创建和销毁小型帮助程序类时对性能的影响。套用《美丽代码》一书中的一句话——“计算机科学中的每个问题都可以用另一个抽象层次来解决”

如果需要,请使用开关。编译器非常擅长为它们生成代码。

  • 你应该重构然后优化。反过来做是没有任何意义的。 (6认同)