Java设计模式帮助

时间:2009-12-21 18:19:13

标签: java design-patterns

您好我正在尝试构建一个将按序列执行的 IAction 对象框架。每个 IAction 实现都将执行其实现的 processAction()方法。此方法返回 IAction ,在大多数情况下,它是自身,但在某些情况下可能是指向List中另一个 IAction 的指针。创建 IActionIterator 接口以管理List中的移动。  这是界面



public interface IAction {
    public IAction processAction();
}

pulbic interface IActionIterator {
    public IAction getFirstAction();
    public IAction getNextAction( IAction action );
}

我的框架将获得列表,并将循环执行每个 IAction 类的 processAction()列表。这是循环的样子



  IActionIterator  iter = ... // created some how
  IAction action = iter.getFirstAction();
  do {
       IAction newAction = action.processAction();
       if( action.equals( newAction ) 
           action = iter.getNextAction( action );
       else 
           action = newAction;

  while( action != null  )  {

因此每个 IAction 都有执行的实现,而某些 IAction 具有将在列表中返回 IAction 的业务逻辑,而不是执行列表中的下一个。

我期待一些将要执行的 IAction 类,但列表中的下一个 IAction 将需要第一个的结果。例如,其中一个 IAction 正在执行SQL查询,结果与列表中的下一个IAction相关。

所以我的问题是在我设计的框架中将 IAction 传递给 IAction 的信息中我将如何实现这一点?

8 个答案:

答案 0 :(得分:2)

听起来你正试图代表状态转换图。您可以使用FSM而不是尝试自己动手吗?

答案 1 :(得分:1)

getFirstAction() / getNextAction()的返回签名更改为简单的持有者对象:

public class IActionResponse {
    List getResultList();
    IAction getReturnAction();
}

答案 2 :(得分:1)

我从未这样做过,但也许您可以使用Serializable接口在Actions之间传递通用信息?然后,Actions会期望某些类型的数据,并知道如何处理它们。

答案 3 :(得分:1)

希望这会有所帮助。我会把它放在界面本身...如果只需要先前操作的结果,否则如果还需要祖先的结果那么更好地将结果存储在一些外部类实例中循环并根据动作ID你可以拉结果..

对于需要先前操作的结果的更简单的情况

IActionIterator {     public IAction getFirstAction();     public getFirstActionResult();     public IAction getNextAction(IAction action); }

答案 4 :(得分:1)

这种情况下,以下类型的界面确实很好:

public interface IAction {
    void invoke(IActionRequest req, IActionResponse res);
}

每个动作从“req”对象获取其输入 - 这些输入是开放式的,可以是任何东西。反过来,每个动作都有机会使用'res'对象来传达输出 - 再次,开放式。

而FWIW,您所描述的框架听起来与某些现有框架非常相似。查看the Cernunnos project,了解一个与您提议的设计非常接近的示例。

答案 5 :(得分:1)

您可以考虑简单地将操作传递给上下文/状态对象(实际上是一个映射)。让操作使用需要传递到链中其他操作的元素填充上下文对象。然后,后续操作可以使用这些元素并根据需要操纵上下文。您需要确保正确排序,因为这就像管理全局状态一样。您可能需要具有多个接口,这些接口仅将特定操作的上下文子集公开。您的控制器可以根据需要检查操作调用之间的上下文。

答案 6 :(得分:1)

我认为你需要的是两种设计模式的组合:Command和Chain of Responsibility

在命令中,您可以封装操作的参数并在操作之间传递数据。您可以记录参数处理,甚至可以根据需要实现撤消功能。实际上,每个命令对象都类似于当前动作处理的上下文。

操作可以使用命令链将控制权传递给对方,其中每个操作都链接到下一个操作。执行其业务逻辑后,操作会调用下一个操作来处​​理向其提供命令对象。

为了使其可扩展到不同的动作类,您还可以在实现责任链时使用模板模板方法。因此,每个动作类将是一些超级动作的子类,它将定义一个模板方法,其中将发生一些命令的预处理,例如检查参数和其他东西。然后将调用子类,然后该模板方法将控制传递给链中的下一个操作。

使用此类模式时,您不需要操作列表和一般循环来处理它们。您只需构造一系列操作,然后在列表中的第一个操作上调用process方法,为其提供命令对象。此外,在构建链时,您还可以自由地混合按您希望的方式处理的动作顺序。不会依赖列表中的操作顺序。

所以,基本上你需要下一个类和接口:

public interface IAction {
     public void process (Command command);
}

public class SuperAction implements IAction {
     private IAction nextAction;

     public void process (Command command) {
           // Check command object

           processAction(command);

           if (nextAction != null)
                nextAction.process(command);
     }

     public abstract processAction(Command command);

     public void setNextAction(IAction action) {nextAction = action;}
}

public class ActionConstructor {
     public IAction constructActoinChain() {
           // construct chain and return first object
     }

}

要完成此操作,您必须使用execute方法定义Command对象。如果没有execute方法,那么Command将只是在操作之间传递的参数的容器。

答案 7 :(得分:0)

一些一般性评论:您正在创建一个有限状态机,它可能是工作流引擎的开始。看一下其他人的尝试是一个想法:

工作流程引擎通常在标准类型的工作流程项目上运行。如果是这种情况,那么您可以将(工作流实现WorkflowItem接口的对象)的(集合)传递给第一个操作,并将其传递给每个下一个操作。这允许引擎通过引用WorkflowItem接口来处理常见的工作流问题。具体操作需要检测子类型。

我在这里没有听到任何人的一个主题是工作流的典型方面:异步处理。通常,您希望能够在某个点之前执行操作,然后保持工作流状态。然后,可以通过某些事件(即,用户登录并做出决定)来触发工作流程以继续。要做到这一点,您需要一个数据层,它可以将通用工作流状态与特定于应用程序的数据分开。

我最近为我正在开发的项目构建了一个成熟的工作流引擎。它是可行的(特别是如果你不试图让它无休止地通用,但将其与手头的问题相匹配),但需要做很多工作。我们决定这样做的原因是现有的框架(jBPM等人)似乎太不灵活和严厉,无法满足我们的需求。我做了很多乐趣!

希望这有帮助。