2011-09-28 79 views
12

救我从猛禽死亡 - 有没有更好的方法来处理这种结构?即将使用goto语句

while(condition) { 
    $this->phase1(); 
    $this->phase2(); 
    $this->phase3(); 
    $this->phase4(); 
} 

纵观这些方法中的任何一个,在条件能否得到满足。 立即条件满足后,回路必须退出。例如,如果我可以在phase2();的内部调用break;例如,我不需要goto语句(但当然,这会引发错误)。

+7

猛禽死亡参考:http://xkcd.com/292/ – amosrivera

+0

Catchy标题。 :-) – Herbert

+0

如果条件变为false,phase1是否也会停止运行? – corsiKa

回答

11

返回一个布尔值来执行每一个阶段,直到成功为止。

while (condition) { 
    if ($this->phase1() || $this->phase2() || $this->phase3() || $this->phase4()) { 
     // Success! 
    } 
} 
+0

如果在阶段1中间满足条件并且您不想等到函数退出,该怎么办? –

+3

该方法假定每个阶段都是一次原子操作,并且只有一次成功/失败测试。如果你在一个可能达到成功状态的阶段有多个案例,那么整个代码很可能只是结构不好。 –

+0

假装它是一款游戏。如果玩家有50分,游戏应该立即说出“你赢了!”而不是等待玩家完成他们的转身。玩家可以在shoot_player()阶段或got_flag()事件或者assist_team()事件期间获得积分,甚至可以在player_death()事件期间获得积分。它应该如何结构呢? –

4

从不同的阶段返回一个布尔值。如果它没有成功,我会返回false,然后检查那个和break

+0

如果我遵循了你的建议,我可能必须在代码中添加〜50条语句链。条件可以通过许多不同的方式来实现,并且这个循环必须立即退出(阅读:尽快满足条件) –

+8

然后我说你有更大的设计问题。 –

+0

我不知道如何构建它。这是一个经典的游戏循环问题,我会想象。玩家可以随时获胜,你不想等待轮到他们完成显示“你赢了!”。您希望它立即显示! –

7

或者您可以使用State pattern

总之,而不是具有goto语句,更改$this这样的内部状态的方法phase1phase2phase3phase4不会产生影响,是空的功能。既然它们是空的函数,你就可以直接通过它们并退出循环!

您可能还需要一小撮事件或Observer模式,才能知道何时更改状态。

+0

我觉得像观察者模式是我在这里寻找的。每次条件变量改变时,它都会通知一个game_won?()函数,该函数检查游戏是否获胜。那么我将如何摆脱游戏循环? –

2

抛出一个异常......听起来很特殊......

try { 
    while(condition) { 
     $this->phase1(); 
     $this->phase2(); 
     $this->phase3(); 
     $this->phase4(); 
    } 
} catch (Exception $e) { } 
+0

这取决于。 @chris - 问问自己“这值得开销吗?”。 –

+1

这可以工作,但它遇到的条件不是严格的错误。这只是一个满足的条件。错误处理仍然是一个好方法吗? –

+2

正如我的朋友Dan juuust所说:“你不用控制流量的例外!”,但是,嘿,我不知道为什么你需要跳出这个执行。也许不是,当我读它时,听起来更加可怕...... – Steve

0

如何包装每个阶段在if

while(condition) 
{ 
    if(condition) 
    { 
    $this->phase1(); 
    } 

    if(condition) 
    { 
    $this->phase2(); 
    } 

    if(condition) 
    { 
    $this->phase3(); 
    } 

    if(condition) 
    { 
    $this->phase4(); 
    } 
} 

当然,这也许可以做得更紧凑有一些规划和循环。

+0

当然,我可以做到这一点。我也可以在if语句中包装所有其他条件会议事件。这很多如果陈述,哟。 –

0

一种方法可能是使用if()语句检查每个phase*()的返回值并打破while循环。

事情是这样的:

while (condition) { 
    if ($this->phase1()) { break; } 
} 
0

请不要使用goto语句,认为谁将会辐照诱导你的代码库

如果您条件这不是太大的开销的编码器,你可以

while(*condition*){ 
    $this->phase1(); 
    if (*condition*){ 
     $this->phase2(); 
    } 

    ... 

} 
0
$phases=array('phase1','phase2','phase3','phase4'); 
foreach($phases as $phase){ 
    $this->$phase(); 
    if(condition)break; 
} 

另外,如果您想从函数内部突破,则可以使用异常。