有很多方法。如果这些状态是枚举值、整数或字符串,则 switch 看起来比许多嵌套的 ifs 更干净,尽管归根结底是同一件事,但最终仍可能会出现一些深层嵌套。
switch (C) {
case STARTED :
{
// do stuff for this state
}
case RUNNING :
{
// do stuff for this state
}
}
在必要时不要忘记break; 声明,否则案件可能会失败。不过,在 return 语句之后就没有必要了。
更进一步的方法是简单地分解方法。
switch (C) {
case STARTED : return handleStartedState(A, B);
case RUNNING : return handleRunningState(A, B);
}
然后,您可以在一个单独的方法中为每个 C 案例实现逻辑,这反过来又对其他输入执行相同的操作。这样做的缺点是,您最终可能会为各种输入组合使用大量具有长名称的方法。
也许更好的面向对象方法是将如何处理各种状态组合的责任放在类本身中。我不知道您的 A、B 和 C 是什么,但如果它们是您控制的类,您可以根据需要在每个委托中创建方法。例如,C 类有一个方法handle(A, B),它根据自己的状态调用A 上的方法,A 然后对B 执行相同的操作。解决此问题的一种方法是使用the state pattern,这是一种将行为与某些对象的状态相结合的设计模式。
这确实意味着您正在创建一些类只是为了处理这个问题,并且它可能会使根本不需要需要那么复杂的事情过于复杂。问自己这些问题:
- 以后会不会有更多的案件需要处理?
- 添加更多案例的情况是否经常发生?
- 是否必须能够以动态方式扩展功能(可能由客户使用代码)?
- 添加新案例会导致代码长度呈指数增长,而不是线性增长吗?
如果其中任何一个是正确的,您可以考虑采用更复杂的方法。但是,如果几十行 if 语句可以很好地完成工作,并且它们不太可能很快改变并且改变不是重构的噩梦,那么它们可能是完成这项工作的正确工具。虽然我重视前期设计并展望未来,但很容易被骗去进行过于通用的设计,最终成为火箭飞船,而自行车就足够了。换句话说,避免being an "architecture astronaut"。开发中的一条众所周知的规则是始终从可能可行的最简单的事情开始。我不认为这是绝对的。如果问题开始扩大,重构可能会变得困难,而某些前期设计可能从一开始就很理想。但通常这是一个很好的初始方法。
还意识到模式可以提供答案,但它们本身的存在得益于其环境的优雅:面向对象编程。 Java 是kingdom of nouns, of "things", when sometimes what you need are verbs, "actions"。函数式编程允许一些需要面向对象模式的事情自然而然地完成,以至于您甚至没有意识到它有一个模式。 Java 8 朝着函数式编程迈出了重要的一步,因此您可能想研究如何链接行为而不是类。
最后,对于倾向于扩展或更改的复杂规则集,您需要查看规则引擎。正如 freedev 在评论中指出的那样,Drools is a Java solution for this。
这个问题没有“一刀切”的答案,因为它过多地依赖于项目、上下文、代码库的其余部分......所以希望上述信息能让您找到最有效的方法。