在Java中重构这个的最佳实践是什么?
while (1) {
// initialisation
for (int i = 0; i < MAX_ATTEMPT; i++) {
if (try_something()) goto step2;
}
continue;
step2:
for (int i = 0; i < MAX_ATTEMPT; i++) {
if (try_next_thing()) goto step3;
}
continue;
step3:
...
}
答案 0 :(得分:3)
首先要确定代码尝试完成的内容:
然后,编写执行此操作的代码,例如:
while (true) {
int i;
for (i = 0; i < MAX_ATTEMPT && !try_something(); ++ i)
;
if (i == MAX_ATTEMPT)
continue;
for (i = 0; i < MAX_ATTEMPT && !try_next_thing(); ++ i)
;
if (i == MAX_ATTEMPT)
continue;
// etc.
}
还有很多其他方式可以表达这一点。例如,您可以将每个步骤分解为一个方法,并利用&amp;&amp; amp;&amp;当一个是假的时候会停止评估它的论点:
boolean doFirstThing () {
int i;
for (i = 0; i < MAX_ATTEMPTS && !try_something(); ++ i)
;
return i < MAX_ATTEMPTS;
}
boolean doSecondThing () {
int i;
for (i = 0; i < MAX_ATTEMPTS && !try_other_thing(); ++ i)
;
return i < MAX_ATTEMPTS;
}
// then, elsewhere
while (true)
doFirstThing() && doSecondThing();
或者其他什么。我不确定我是否会将后者称为“最佳实践”,因为它有点混淆(这并不是说它在某些情况下不合适),但它只是一个例子。通常,当移植到另一种语言时:分析原始 - &gt;该怎么办? - &GT;重新实现目标语言。优先级是代码正确性,第二个(但不远)是清晰度。
答案 1 :(得分:2)
对于文字,但不是最好的翻译,你可以做。使用break作为goto不是一个好主意,除非你必须生成代码并且没有简单的方法。
while (true) {
// initialisation
step2:
{
for (int i = 0; i < MAX_ATTEMPT; i++) {
if (try_something()) break step2;
}
continue;
}
step3:
{
for (int i = 0; i < MAX_ATTEMPT; i++) {
if (try_next_thing()) break step3;
}
continue;
}
step4:
...
}
答案 2 :(得分:2)
我很想封装这些步骤并使用类似状态机的东西:
enum Step {
STEP1 {
@Override
public Step attempt() {
for (int i = 0; i < MAX_ATTEMPT; i++) {
if (try_something()) return STEP2; // advance to next step
}
return STEP1; // return to step 1
}
},
STEP2 {
@Override
public Step attempt() {
for (int i = 0; i < MAX_ATTEMPT; i++) {
if (try_next_thing()) return STEP3; // advance to next step
}
return STEP1; // return to step 1
}
},
STEP3 { /* etc. */ },
. . .
;
public abstract Step attempt();
}
然后(如果我理解原始的意大利面条逻辑)你可以把你的循环编写为:
Step step = Step.STEP1;
while (1) {
// initialisation
step = step.attempt();
}
答案 3 :(得分:1)
也许不是最好的解决方案,但我通常会这样做:
boolean success = false;
for (int i = 0; i < MAX_ATTEMPT && !success; i++) {
success = try_something()
}
if (success) {
success = false;
for (int i = 0; i < MAX_ATTEMPT && !success; i++) {
success = try_next_thing();
}
}
希望有所帮助。
答案 4 :(得分:0)
我首先将C代码重构为一些不那么重复的东西:
enum { STEP1, STEP2, STEP3, /*...*/ };
typedef int ThingToTry();
ThingToTry *things_to_try[MAX_STEP] = {
try_something,
try_next_thing,
/*...*/
};
int next_step (int (*thing_to_try)(), int true_step, int false_step) {
for (int i = 0; i < MAX_ATTEMPT; i++) {
if (thing_to_try()) return true_step;
}
return false_step;
}
/*...*/
step = STEP1;
while (step != MAX_STEP) {
if (step == STEP1) {
/*...initialization */
}
step = next_step(things_to_try[step], step+1, STEP1);
}
Java中的相应代码:
enum StepEnum { STEP1, STEP2, STEP3, //...
}
interface ThingToTry {
bool do_it ();
}
class TrySomething extends ThingToTry //...
class TryNextThing extends ThingToTry //...
StepEnum next_step (ThingToTry thing_to_try,
StepEnum true_step, StepEnum false_step) {
for (int i = 0; i < MAX_ATTEMPTS; ++i) {
if (thing_to_try.do_it()) return true_step;
}
return false_step;
}
//...
ThingToTry[MAX_STEP] things_to_try = {
new TrySomething,
new TryNextThing,
//...
};
while (step != MAX_STEP) {
if (step == STEP1) {
//...initialization
}
StepEnum true_step = StepEnum.values()[step.ordinal()+1];
step = next_step(things_to_try[step.ordinal()], true_step, STEP1);
}
答案 5 :(得分:0)
对我来说最有效的是在功能之间划分逻辑,这就是我的想法:
bool attempt_something() {
for(int i = 0; i < MAX_ATTEMPT: i++) {
if (try_something())
return true;
}
return false;
}
bool attempt_something_else() {
for(int i = 0; i < MAX_ATTEMPT: i++) {
if (try_something_else())
return true;
}
return false;
}
你的同时将成为
while (1) {
if (!attempt_something())
continue;
if (!attempt_something_else())
continue;
...
}
答案 6 :(得分:0)
首先将代码转换为C语言中的面向对象设计。您的代码本质上是一个状态机,因此您应该能够用一个代替它。
典型的基于函数指针的状态机示例:
typedef bool (state_t*)(void);
state_t state [STATES_N] = { // array of function pointers
&try_something,
&try_next_thing,
...
};
int state = 0;
while (1) {
for (int i = 0; i < MAX_ATTEMPT; i++) {
if(try[state]()) {
state++;
if(state == STATES_N) {
state = 0;
}
}
}
}
要将其转换为Java OO,我想你会将每个状态交换为类的对象,其中类具有try函数。