大型嵌套switch语句的设计模式

Kev*_*vin 5 oop polymorphism design-patterns switch-statement

我搜索了一些关于重构大型switch声明的文章.

但他们没有做我想做的事.我要运行的问题是有一个巨大的switch语句,根据两个不同的值调用不同的方法,让我们说a type和a code.

目前,我会处理这样的情况:

switch (type)
{
    case Types.Type1:
        handleType1(code);
        break;

    case Types.Type2:
        handleType2(code);
        break;
}

void handleTypeN(code)
{
    switch (code)
    {
       ...
    }
}
Run Code Online (Sandbox Code Playgroud)

也许结合了工厂和命令模式的东西会帮助我吗?我一定错过了一些明显的东西.

你会如何重构这段代码?


我可能需要更具体地了解我面临的情况.

我正在接收来自服务器的数据包.数据包包含类型和代码以及一些特定信息.

由于数据到达不久,我检索typecode数据包,并且它去到switch该语句type,搞清楚后type的特定方法被调用,以在执行交换机code的数据包.

处理代码的方法现在进一步解码数据包并完成该过程.

+----------+                +----------+
|          |     Packet     |          |
|  Server  | -------------> |  Client  |
|          |                |          |
+----------+                +----------+
                                  |
                                  |
         (Switch on the type of the packet and call a specific method)
                                  |
                                  |
         (Switch on the code of the packet and call a specific method)
                                  |
                                  |
                    (Respond to the server or not)
Run Code Online (Sandbox Code Playgroud)

Dam*_*RAS 5

2 模式进入脑海:命令和访问者:http : //en.wikipedia.org/wiki/Command_pattern http://en.wikipedia.org/wiki/Visitor_pattern

Abstract Class Command {

 executeSomething();

}
Class typeN extends command {

   executeSomething() {
    //...
   }
}

Class typeM extends command {

   executeSomething() {
    //...
   }
}

replace your switch by :
//my old switch
class commandManager {

processCommand() {
for listOf command in a command buffer
{ 
 onCommand(listOfcommand.command)
}
}
 onCommandPoped(command type) {
  type.executeSomething()
 }

}

you can pass parameters to executeSomething, and you can pass another command


the client code : 

{
 commandN = new CommandN()
 commandManager.postCommand( commandN)
}
Run Code Online (Sandbox Code Playgroud)

阅读您的数据包服务器用例后,我认为您可以使用策略模式的变体 http://www.oodesign.com/strategy-pattern.html ,您可以在其中选择在数据包到达时调用的策略,您可以使用工厂。

但你不会杀死你的开关盒

请记住,一个服务器可以为多个客户端提供服务。如果可能是您的 switch case 比对象实例化更快。


Yoc*_*mer 3

我认为这取决于您想要进行什么样的代码改进。

如果您有能力实际进行重大设计更改,那么我建议使用多态性:

创建一个抽象 Packet 类。
为每种数据包类型创建一个类。
创建一个工厂方法,用于接收原始服务器数据包,并创建正确的数据包类对象。
每个数据包类类型都会有其自己所需完成的工作的实现。

如果您没有能力进行大型设计更改(通常是这种情况):

  • 如果你想提高可读性:

保持开关状态,每个开关情况都会调用一个正确命名的函数来执行它需要的操作。

  • 如果你想提高性能:

创建一个矩阵,每个单元格 [T,C] 将保存对处理类型 T 和代码 C 的数据包的函数的引用。
该矩阵应在启动时启动一次(硬编码,无法绕过)课程或课程的。
这将为您提供比长 switch 块更好的性能(直接访问代码,没有逻辑比较)