我可以在函数中设置状态吗?

时间:2011-01-26 17:46:15

标签: algorithm delphi optimization

我有这段代码:

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吗?

这是代码味吗?

如果是的话,你能建议我一个更好的方法吗?

3 个答案:

答案 0 :(得分:4)

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

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

如果上述任何一种情况适用,请不要使用内部方法。

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

答案 1 :(得分:2)

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

答案 2 :(得分:0)

我会说新代码有点气......

这完全取决于您在当前代码中管理的状态数量,以及状态数量是否可能在未来发生变化。请注意 设置状态的方式和时间,并注意 检查状态的方式和时间。< / p>

在您显示的两个代码段中,存在细微差别:

在第一个原始代码中,通过迭代保留当前状态,并且在迭代的开始中设置新的错误状态,并且始终检查。

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

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

如果您想要一路走下去,研究GoF的州设计模式,那么请看一下这些页面: