2011-01-26 114 views
3

我有这样的代码:我可以在一个函数中设置一个状态吗?

procedure EstablishCommunication; 
var 
    State   : TStates; 
    Attempts  : Byte;  
    procedure IncAttempts; 
    begin 
     Inc(Attempts); 
    end; 
begin 
    State := stReadDeviceID; 
    Attempts := 0; 

    while True do 
    begin 
     if Attempts >= MAX_ATTEMPTS then 
     begin 
      State := stError; 
     end; 
     case State of 
      stReadDeviceID: 
      begin 
       // some code 
       IncAttempts; 
      end; 
      stError: 
      begin 
       // Error code 
      end; 
     ... 
     ... 
     ... 

我希望把该程序IncAttempts内设置状态stError,造成代码:

procedure EstablishCommunication; 
var 
    State   : TStates; 
    Attempts  : Byte;  
    procedure IncAttempts; 
    begin 
     Inc(Attempts); 

     if Attempts >= MAX_ATTEMPTS then 
     begin 
      State := stError; 
     end; 
    end; 
begin 
    State := stReadDeviceID; 
    Attempts := 0; 

    while True do 
    begin    
     case State of 
      stReadDeviceID: 
      begin 
       // some code 
       IncAttempts; 
      end; 
      stError: 
      begin 
       // Error code 
      end; 
     ... 
     ... 
     ... 

所以,我可以将代码移到IncAttempts?

这是代码味道吗?

如果是的话,你可以给我一个更好的方法吗?

+0

它取决于..状态是一个局部变量,所以当max_attempts被创建时,你的过程会做什么?它看起来像是一个错误条件,是引发异常的好地方。但是,总是取决于... – jachguate 2011-01-26 18:03:50

+0

这是一块有限状态机。我正计划在stError状态中引发一个异常。我编辑了代码,试图更好地解释。 – 2011-01-26 18:19:51

回答

4

我会认为这是完美的有效代码。在另一个方法中声明方法时,我会问自己以下问题。大多数时候我不这样做,但有时候会导致更好的代码。

  • 内部函数是否需要像后代类一样改变?
  • 我可以在不调用内部方法的情况下重写External方法吗?
  • 内部函数在外部方法之外有实际应用吗?
  • 内部函数是否足够复杂,应该在外部方法的范围之外进行单元测试?

如果上述任何适用不使用内部方法。

但是,如果您没有上述任何一项,它可以删除重复代码和/或简化设计,那么您可以考虑使用内部函数。

2

没有真正的问题,应该工作得很好。你已经在修改另一个局部变量Attempts,所以没有理由修改State应该闻到更多。 我认为你应该小心使用内联函数。代码通常最终难以阅读/理解。

0

我要说的是新代码有一些味儿......

这一切都取决于你在当前的代码有多少国家管理的,如果状态的数量可能会在未来发生改变。谨防如何和何时你设置的状态,并提防如何和何时你检查的状态

在告诉你这两个代码片段,有一个微小的差别:

在第一,原代码,目前国家正在通过反复保存,新的错误状态在开始设置迭代的,它是总是检查

在第二个重构代码中,状态在迭代过程中发生了变化,只有在状态为stReadDeviceID时才会改变状态。

现在,如果在这个while True do -iteration最后一行是if State = stError then Break;,那么你的第一个代码将要运行的迭代一次,改变状态stError在开始的时候如果迭代。您的第二个代码将在当前迭代结束时退出,并且case-语句的-部分中的代码将永远不会执行...

如果您想要一路走下来,学习GoF的状态设计模式,然后看看这些网页:

相关问题