一个多步骤算法的设计模式

6
我正在编写一款控制台应用程序,该程序经过N个步骤的算法。重要的是,在执行步骤N+1之前必须正确执行第N步。否则,程序应该停止工作并显示错误消息。当然我可以使用嵌套的if语句和try-catch-finally语句(在finally中使用继续标志来决定程序是否应该继续处理)。但我正在寻找更好的结构化设计模式或方法来完成此任务。有什么建议吗?

1
你能提供更多关于你的算法的信息吗?这似乎可以使用 While 循环完成。 - Bas
1
递归是否可行? - Jonesopolis
2
你可以考虑使用状态机方法吗? - Belogix
1
我们需要更多的细节。就目前而言,任何描述控制流程的命令式编程语言都是一种解决方案。 - P.Brian.Mackey
6
我正在尝试理解你问题描述与“每个”计算机程序的区别。我编写的每个程序都执行一系列步骤,其中下一步的正确性取决于前一步的成功。 - Eric Lippert
显示剩余3条评论
6个回答

10
流水线(Pipeline)设计模式正是为此而生:在严格的步骤序列中执行复杂的过程。搜索“pipeline design pattern”即可找到大量资源。 这篇文章是MSDN上面面向程序员的入门介绍,而这篇则是更加理论化的文章。

7
责任链模式,或状态模式可能是解决您问题的方案。对于责任链模式,当检测到错误时,您只需要将“错误消息处理”设置为链中的下一个处理过程。对于状态模式,当遇到错误时,您需要将状态更改为“错误”,并在错误状态下处理所有错误。希望这有所帮助。
参考链接: 责任链模式:http://www.codeproject.com/Articles/455228/Design-Patterns-3-of-3-Behavioral-Design-Patterns#Chain 状态模式:http://www.codeproject.com/Articles/455228/Design-Patterns-3-of-3-Behavioral-Design-Patterns#State

3

我曾经创建过一个控制自动化的进程,使用了包含所有步骤的枚举。

enum AutomationStep{Requested, Started, Waiting, Processing, Terminating};

稍后我创建了一个switch/case来以不同的方式处理每个步骤。
switch (currentStep)
{
  case AutomationStep.Requested : InitializeProcess(); currentstep = AutomationStep.Started; break;
  case AutomationStep.Started : StartTheEngines(); currentstep = AutomationStep.Waiting; break;
  case AutomationStep.Waiting : //etc
   break;
   default:
}

您可以稍后使用While来运行每一步。

这是一个不错的答案,在低级编码中经常使用,我只想补充一点,这种模式通常用于实现状态机。 - Lorenzo

1
您可以选择以下任意一种方式实现:
  1. 责任链模式。
  2. 维护一个处理流程列表并循环执行。
  3. 使用函数组合将函数链接在一起。在 Java 8 中,您可以通过使用 Java 8 函数接口来实现此目的。

Java 8 APIs 中的一个示例是使用比较器接口。

下面是一个使用函数组合链接函数的示例:

Comparator.comparing(name).thenComparing(age).

点击这里查看有关此事的详细文章。


0

使用递归,在遇到错误步骤时返回或停止

public void Process(int n)
{
 if( n % 23 != 0 )return;
 Process(n+1);
}

n 将会是你的工作数据集或当前项。你需要自己确定使用哪种数据结构。同时,对23取模检查是为了在递归检查时判断何时应该跳出。


1
但是算法是按步骤进行的...即第1步:确定参数是否为偶数。第2步:将参数乘以3。第3步:添加参数...因此,递归在这里不起作用,因为步骤是会改变的。 - neeKo
@NikoDrašković - 一种方法是将步骤存储在操作中,然后使用int操作字典。这将是“数据结构”方面的内容。 - Travis J
如果你有一个操作集合,你只需要使用foreach循环。递归没有意义。你所编写的递归本质上是一个for(int n = 0; n < 23; n++) { .. },带有完全不必要的开销。 - neeKo
@Niko - 一个foreach循环或简单的for循环无法将信息传递到下一步,除了迭代器之外。int只是一个示例。对不起,你无法可视化除了int之外的任何传递内容。 - Travis J
我可以,但如果你总是传递相同类型的数据结构,你可以在迭代步骤之间将其存储。 - neeKo
@Niko - 但是这样做有什么乐趣呢?我认为这个问题有点太模糊了,无法得到适当的解答。因此,我们可能会花费一整天来推测完成同一件事情的多种方式。 - Travis J

0

我喜欢的一种模式是在对象从一个步骤到下一个步骤时更新其状态,以指示它在过程中的位置。

与其从头到尾处理一个对象,我让算法的每个步骤选择处于给定状态的所有对象,对它们进行处理,并更新它们的状态以准备好下一步。

我将处理过程的每个步骤都作为一个事务,这样一个对象要么完全进入下一步,要么回滚到其先前的状态并准备再次经历此步骤。

这样,如果您的程序在中途被中断,您只需重新启动它,所有对象就可以在过程中恢复到它们离开的地方。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接