delphi – 如何在没有大量IF的情况下控制执行?
我有一个过程,从文件导入数据开始,然后执行一系列过程,但在任何时候它都可以找到问题,应该停止执行其余的并运行另一个集合.
这是我的示例,其中每个过程设置全局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: 我想保持工作流程从主程序(运行)控制,这样我就可以看到主要导入后运行的所有任务.如果我将执行分解为许多较小的过程,我只会看到更多的混淆,更少的可读性和可维护性.然后我可以: 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; 此工作流程似乎没有正确设计.我想知道在导入后运行的主要任务是什么,而不是每次我需要查看它时都不进行发现之旅.所有任务都已按目的分组到程序中,它们执行的操作以及执行方式和结果. 结论: 虽然不是最好的选择,但我决定在需要停止进程时使用Raising Exception.我有点’理解这种方法带来的影响(一旦我实现它就会知道更多),但它似乎是朝着更好地实现整个过程的一个合乎逻辑的步骤.现在我不会为每个任务执行都看到所有这些IF.好!代码将更易读,更易于维护. 我阅读了提供的链接,以解释在停止工作流程执行中使用Exceptions的缺陷,但正如Dalija Prasnikar在评论中所解释的那样,这不是与任务相关的性能部分;每个应用程序运行只执行一次进程;任务已经完成了他们的工作;任务已经包括多个IF语句,其中检查停止的进程等等,所以我认为异常不会成为我的问题的一个非常糟糕的解决方案. 此外,如果我将任务转换为返回结果的函数,我想我会遇到同样的问题,检查每个任务的值,并根据它停止或继续该过程. 所以,提高异常是我选择的. 解决方法
您应该使用自定义异常,并在遇到打破工作的原因并转到Stopped代码时提高它.在Import,AfterImport1和其他代码逻辑中只调用Stop过程,它将执行Stopped过程.另一方面,如果一切顺利,将不会调用Stopped.
您可以从EAbort派生异常创建静默异常 type EStopException = class(EAbort); 或者从基础Exception类派生以使用常规类型异常. type EStopException = class(Exception); procedure Stop(const Msg: string); begin raise EStopException.Create(Msg); end; procedure Import; var sl: TStringList; begin sl := TStringList.Create; try // your code logic if NeedToStop then Stop('something happened'); finally // perform any cleanup code needed here sl.Free; end; end; procedure Stopped; begin end; procedure Run; begin try Import; AfterImport1; AfterImport2; except on e: EStopException do Stopped; end; end; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |