如何避免代码重复?
在这种情况下是否可以避免代码重复? (Java 代码)
void f()
{
int r;
boolean condition = true;
while(condition)
{
// some code here (1)
r = check();
if(r == 0)
break ;
else if(r == 1)
return ;
else if(r == 2)
continue ;
else if(r == 3)
condition = false;
// some code here (2)
r = check();
if(r == 0)
break ;
else if(r == 1)
return ;
else if(r == 2)
continue ;
else if(r == 3)
condition = false;
// some code here (3)
}
// some code here (4)
}
int check()
{
// check a condition and return something
}
一个可能的解决方案可能是使用异常,但这似乎不是一个好的做法。 在这种情况下,有什么所谓好的程序流程控制模式吗?例如,从 check()
函数内部调用 break ;
的方法。 (可能是其他编程语言)
Is it possible to avoid code duplication in such cases? (Java code)
void f()
{
int r;
boolean condition = true;
while(condition)
{
// some code here (1)
r = check();
if(r == 0)
break ;
else if(r == 1)
return ;
else if(r == 2)
continue ;
else if(r == 3)
condition = false;
// some code here (2)
r = check();
if(r == 0)
break ;
else if(r == 1)
return ;
else if(r == 2)
continue ;
else if(r == 3)
condition = false;
// some code here (3)
}
// some code here (4)
}
int check()
{
// check a condition and return something
}
A possible solution may be using Exceptions, but that doesn't seem to be a good practice.
Is there any so-called good pattern of program flow control in such cases? For example, a way to call break ;
from inside the check()
function.
(Possibly in other programming languages)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
对于一个棘手的问题,有一些很好的答案(尤其是@Garrett 刚刚的答案),但我会为后代添加 0.02 美元。
关于如何在不看到实际代码的情况下重构这个块,这里没有简单的答案,但我对此的反应是它需要重新设计。
如果您要求 Java 不支持的不同中断(无需破解)并且有重复的
check()
和各种不同的循环退出/重复代码向我指示这是一个庞大而复杂的方法。以下是一些供您思考的想法:每个
some code here
块都在做一些事情。如果将它们拉出到它们自己的方法中,这会如何改变循环?也许可以将循环分解为一系列注释。不要深入研究代码,而是从概念上考虑一下,看看是否会出现不同的配置。
您的组织中是否有其他未参与此代码的开发人员查看过该代码?如果您详细解释代码如何工作,某人可能会看到一些您看不到的模式,因为您身处杂草之中。
我还认为@aix 的有限状态机的想法是一个很好的想法,但我在我的编程之旅中很少需要使用这种机制——主要是在模式识别期间。我怀疑重新设计代码并将更小的代码块引入方法将足以改进代码。
如果您确实想实现状态机,这里有一些更多细节。您可以有一个仅运行调用方法的单个 switch 语句的循环。每个方法都会返回开关的下一个值。这与您的代码不完全匹配,但类似于:
希望其中一些有所帮助,祝您好运。
Some good answers (especially @Garrett's just now) to a tough question but I'll add my $0.02 for posterity.
There is no easy answer here about how to refactor this block without seeing the actual code but my reaction to it is that it needs to be redesigned.
If you are asking for a different break that Java does not support (without a hack) and having the duplicated
check()
and various different loop exit/repeat code indicates to me that this is a large and complicated method. Here are some ideas for you to think about:Each of the
some code here
blocks are doing something. If you pull those out to their own methods, how does that change the loop?Maybe break the loop down into a series of comments. Don't get deep into the code but think about it conceptually to see if a different configuration drops out.
Have you had another developer in your organization who is not involved with this code take a look at it? If you explain in detail how the code works someone they may see some patterns that you are not since you are in the weeds.
I also think that @aix's idea of a finite state machine is a good one but I've needed to use this sort of mechanism very few times in my programming journeys -- mostly during pattern recognition. I suspect that a redesign of the code with smaller code blocks pulled into methods will be enough to improve the code.
If you do want to implement the state machine here are some more details. You could have a loop that was only running a single switch statement that called methods. Each method would return the next value for the switch. This doesn't match your code completely but something like:
Hope some of this helps and best of luck.
避免这种重复的最好方法是通过保持方法小而集中来避免这种情况发生。
如果
// some code here
块不是独立的,那么您需要先发布所有代码,然后才能有人帮助您重构它。如果它们是独立的,那么就有办法重构它。The best way to avoid this duplication is not to let it happen in the first place by keeping your methods small and focused.
If the
// some code here
blocks are not independent, then you need to post all the code before someone can help you refactor it. If they are independent then there are ways to refactor it.代码味道
首先,我赞同aix的回答:重写你的代码!为此,状态设计模式可能会有所帮助。我还想说,以这种方式使用中断、继续和返回与代码重复本身一样是一种代码味道。
话虽如此,这里有一个解决方案,只是为了好玩
它使用了闭包。当然,参数 r0Block 和 r2Block 可以省略,而将 codeBlock4() 和 f() 硬编码在distinction() 内。但是,distinction() 只能由 f() 使用。对于 Java <=7,您需要使用带有 invoke() 方法的接口,并有 4 个实现 codeBlock1 到 codeBlock4。当然,这种方法根本不可读,但非常通用,它适用于代码块内的任何业务逻辑,甚至任何中断/返回/继续狂欢。
Code smell
First of all, I second aix's answer: rewrite your code! For this, the state design pattern might help. I would also say that using break, continue and return in such a way is just as much a code smell as the code duplication itself.
Having said that, here is a solution, just for fun
This uses closures. Of course the parameters r0Block and r2Block could be ommited and instead codeBlock4() and f() hard-coded within distinction(). But then distinction() would only be usable by f(). With Java <=7, you would need to use an Interface with the method invoke() instead, with the 4 implementations codeBlock1 to codeBlock4. Of course this approach is not at all readable, but so general that it would work for any business logic within the codeBlocks and even any break/return/continue-orgy.
并不真地。
第二个继续是多余的(您的代码无论如何都会继续)。
尝试使用 Switch 语句。它将使您的代码更具可读性。
Not really.
The second continue is redundant (your code would continue anyway).
Try using the Switch statement. It will make your code more readable.
一种更好的方法是使用 switch 语句,如下所示:
One nicer way to do it would be to use switch statements, something like this:
您可能需要考虑将逻辑重新表述为状态机。它可能会简化事情,并且可能会使逻辑更容易遵循。
You might want to think about re-formulating your logic as a state machine. It might simplify things, and will probably make the logic easier to follow.