Java 重构(C)伪代码以删除goto
在Java中重构的最佳实践是什么Java 重构(C)伪代码以删除goto,java,c,goto,Java,C,Goto,在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; } con
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:
...
}
while(1){
//初始化
对于(int i=0;i
您首先要确定代码试图实现的目标:
- 反复执行以下操作:
- 调用try_something(),最多可调用MAX_尝试次数,如果从未返回true,则重新启动
- 调用try_next_thing(),最多可调用最大尝试次数,如果从未返回true,则重新启动
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.
}
while(true){
int i;
对于(i=0;i
还有很多其他的表达方式。例如,您可以将每个步骤分解为一个方法,并利用这样一个事实,即当一个参数为false时,&&将停止计算它的参数:
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();
boolean doFirstThing(){
int i;
对于(i=0;i
或者别的什么。我不确定我是否会称后者为“最佳实践”,因为它有点模糊(这并不是说它在某些情况下不合适),但它只是一个例子。一般来说,当移植到另一种语言时:分析原文->它应该做什么?->在目标语言中重新实现。优先考虑的是代码的正确性,其次(但不远落后于)是清晰性。对于字面意思,但不是你能做的最好的翻译。使用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:
...
}
while(true){
//初始化
步骤2:
{
对于(int i=0;i
也许不是最好的解决方案,但我通常会:
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();
}
}
boolean success=false;
for(int i=0;i
希望这会有所帮助。我会首先将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);
}
enum{STEP1,STEP2,STEP3,/*…*/};
typedef int ThingToTry();
ThingToTry*要尝试的事情[MAX\u STEP]={
试试看,
试试下一件事,
/*...*/
};
int下一步(int(*要尝试的东西)(),int真步,int假步){
对于(int i=0;i
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);
}
枚举步骤枚举{STEP1,STEP2,STEP3,//。。。
}
接口组件{
bool do_it();
}
类TrySomething扩展了ThingToTry/。。。
类TryNextThing扩展ThingToTry/。。。
步骤列举下一步(要尝试的事情),
步骤枚举真步骤,步骤枚举假步骤){
对于(int i=0;i
我很想封装这些步骤,并使用类似于状态机的东西:
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();
}
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;
}
}
}
}
对我来说,最有效的方法是在函数之间拆分逻辑,我的想法如下:
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;
}
首先将代码转换为C语言中的面向对象设计。您的代码本质上是一个状态机,因此您应该能够用状态机替换它 典型的基于函数指针的状态机示例:
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();
}
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;
}
}
}
}
typedef bool(state_t*)(void);
state\u t state[STATES\u N]={//函数指针数组
&试试看,
&试试下一件事,
...
};
int state=0;
而(1){
对于(int i=0;i
要将其转换为Java OO,我想您可以将每个状态交换为一个类的对象,其中该类有一个try函数。至于抑制gotos,其他提供了答案。至于java部分:您的期望是什么?你在寻找面向对象的重构吗?不,只是简单的流控制。为什么要重构这段代码?代码可读且易于理解。你为什么不删除
goto
语句?@Bart-Java没有goto。[:blush:]我误解了你的问题。我以为你想用C进行重构。你会想在第一次发现成功后停止循环。@Lundin这就是为什么循环条件会添加&&!成功
addon。对不起,下次我会仔细看:)这很可爱,但OP要求重构成Java,而这不是Java。@TedHopp:我是先重构C代码的。谢谢,我已经做了你的第一个解决方案,但我不喜欢I的范围。看