我有这段代码:
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 :(得分:4)
我认为这是完美有效的代码。在另一个方法中声明方法时,我会问自己以下问题。大多数时候我不这样做,但有时它会产生更好的代码。
如果上述任何一种情况适用,请不要使用内部方法。
但是,如果您没有上述任何内容,并且可以删除重复的代码和/或简化设计,那么您可以考虑使用内部函数。
答案 1 :(得分:2)
没有真正的问题,应该工作得很好。您已经在修改另一个本地变量Attempts
,因此没有理由为什么修改State
应该嗅到更多。
我认为你应该小心使用内联函数。代码通常最终难以阅读/理解。
答案 2 :(得分:0)
我会说新代码有点气......
这完全取决于您在当前代码中管理的状态数量,以及状态数量是否可能在未来发生变化。请注意 设置状态的方式和时间,并注意 检查状态的方式和时间。< / p>
在您显示的两个代码段中,存在细微差别:
在第一个原始代码中,通过迭代保留当前状态,并且在迭代的开始中设置新的错误状态,并且始终检查。
在第二个重构代码中,状态在迭代的中间发生变化,只有在状态为stReadDeviceID
时才会改变。
现在,如果此while True do
- 迭代中的最后一行是if State = stError then Break;
,那么您的第一个代码将再次运行迭代,并在开始时将状态更改为stError
迭代。您的第二个代码将在当前迭代结束时退出,并且stError
- case
- 语句中的代码将永远不会被执行...
如果您想要一路走下去,研究GoF的州设计模式,那么请看一下这些页面: