我有一个流程,首先从文件中导入数据,然后执行一系列的过程,但是在任何时候都可能出现问题,应该停止执行其余的过程,并运行另一组过程。
这里是我的示例,每个过程设置全局变量gStop,指示停止该过程。如果已经停止,我需要在最后运行一些代码。
var gStop:boolean;
procedure Run;
begin
gStop:=False;
Import; // imports data from file
If Not gStop Then
AfterImport1;
If Not gStop Then
AfterImport2;
If Not gStop Then
AfterImport3;
If Not gStop Then
AfterImport4;
If Not gStop Then
If fTypeOfData = cMSSQL Then // function returns type of imported data
begin
ProcessMSSQLData1;
If not gStop Then
ProcessMSSQLData2;
If not gStop Then
ProcessMSSQLData3;
If not gStop Then
If fObjectAFoundInData Then // function checks if ObjectA was found in imported data
ProcessObjectA;
If not gStop Then
ProcessMSSQLData4;
end;
If Not gStop Then
AfterImport5;
...
// If stopped at anytime
If gStop then
begin
LogStoppedProcess;
ClearImportedData;
...
end;
end;
在我的情况下,代码行数实际上超过了200行,所以当我维护这部分代码时,我必须来回滚动。
有没有办法改进这个过程,使其更易读、易于维护或者有没有其他方法可以在不使用所有IF的情况下停止这个过程?
编辑1:
每个过程都可以找到错误数据并设置
gStop := True;
,当gStop=True;
时,该过程应跳过所有剩余的过程,并仅执行最后一部分代码。编辑2:
我希望从主过程(Run)控制工作流程,这样我就可以看到主要导入之后运行的所有任务。如果我将执行分成许多较小的过程,我只会看到更多的混乱和较少的可读性和可维护性。那么我只需要:
procedure Run;
begin
gStop:=False;
Import; // imports data from file
RunEverytingAferImport; // execute ALL tasks after import
// If stopped at anytime
If gStop then
begin
LogStoppedProcess;
ClearImportedData;
...
end;
end;
这个工作流似乎设计得不正确。我想知道导入后主要运行的任务是什么,而不需要每次都进行发现之旅。所有任务已经按照目的、它们所做的事情以及它们如何完成分组到程序中,并给出结果。
结论:
尽管不是最好的选择,但当需要停止过程时,我决定采用引发异常的方法。我“有点”理解这种方法带来的影响(一旦我实施它,将了解更多),但这似乎是迈向整个过程更好实施的逻辑步骤。现在我不会看到每个任务执行的所有IF语句。很好!代码将更易读、可维护。
我阅读了提供的链接,以解释在停止工作流执行时使用异常的缺陷,但是,正如Dalija Prasnikar在注释中解释的那样,这不是任务的性能相关部分;该过程每次应用程序运行时只执行一次;任务已经相当结构化,按照它们所做的事情分组;任务已经包括多个IF语句,在其中检查停止进程等等,因此我认为异常并不是一个真正糟糕的解决方案。
此外,如果我将任务转换为返回结果的函数,我认为我将遇到同样的问题,检查每个任务的值并根据该值停止或继续过程。
因此,我选择了引发异常的方法。
try...finally
并抛出一个异常。 - Andreas Rejbrand