Validation ddd状态模式验证通知

Validation ddd状态模式验证通知,validation,design-patterns,notifications,domain-driven-design,state-pattern,Validation,Design Patterns,Notifications,Domain Driven Design,State Pattern,在我的DDD项目中,我试图用JavaEnum实现状态模式 我在验证实体方法时遇到问题,这些方法的行为取决于状态 对于验证,我使用通知模式 我遵循始终有效的实体方法,因此在每次操作中,我首先调用isValidForOperation验证方法 以下是代码,只是为了简单起见: 实体: public class Task extends AggregateRoot<TaskId> { ... private State state; ... // Ope

在我的DDD项目中,我试图用JavaEnum实现状态模式

我在验证实体方法时遇到问题,这些方法的行为取决于状态

对于验证,我使用通知模式

我遵循始终有效的实体方法,因此在每次操作中,我首先调用isValidForOperation验证方法

以下是代码,只是为了简单起见:

实体:

public class Task extends AggregateRoot<TaskId> {

    ...
    private State state;
    ...


    // Operation with behaviour depending on the state
    // It's a transition from "ASSIGNED" state to "IN_PROGRESS" state
    // I apply the state pattern here

    public void start () {
        State next = this.state.start ( this );
        this.setState ( next );
    }

    ...
}
验证方法遵循通知模式。 它收集通知对象中所有可能的错误。 此通知对象被传递给异常。 抛出异常,然后应用程序层捕获它并将所有错误消息返回给客户端

public void assertTaskIsValidForStart ( Task task ) {

        Notification notification = new Notification();
        if ( errorCondition (task) ) {
            notification.addError(...);
        }
        ...
        // more errors
        ...
        if ( notification.hasErrors() ) {
            throw new TaskNotValidForStartException ( notification.errors() );
        }

    }
当错误条件是状态之间的无效转换时,通知模式如何与状态模式结合应用

有什么想法吗

更新:

我找到了解决办法。我将依赖于状态的整个操作放在实体中,并将状态模式应用到更细粒度的代码中。这样我就可以应用模式来计算下一个状态,这样我就可以检查是否允许转换,并应用通知模式

代码:


我认为你的枚举做得太多了。 除了有一组几乎无法扩展的固定状态外,您还很难为每个具体状态引入任何形式的合同,这也将解决您的通知问题

引入一个抽象状态类,它是所有具体状态的基类。传递一个允许为每个状态设置后续状态的上下文。此上下文可以由聚合根实现。 每个状态都可以使用AbstracftState强制管理通知,例如,强制状态执行返回通知对象:

interface StateContext {
   setState(AbstractState state);
}

class AbstractState {
    abstract Notification execute(StateContext context);
}

class Task extends AggregateRoot implements StateContext {
    AbstractState currentState;

    ....

    public void start() {
        Notification n = currentState.execute(this);
        if (n.hasErrors()) {
            throw new Exception(n.toErrorReport());
        }
    }
}

现在,您可以在执行之前或之后收集每个状态的错误。您可能希望在执行之前调用的每个AbstractState中引入validateStart,并将收集到的错误报告给调用者。

我会将TaskWorkflow建模为任务聚合中的VO

class Task {

    private Workflow workflow;

    public void start() {
        workflow = workflow.followWith(Action.START, this);
    }

    public State currentState() {
        return workflow.state();
    }

    public List availableActions() {
        return workflow.nextActions();
    }

}
工作流是一个FSM,由操作连接的状态之间的转换组成。对工作流方法的任何调用都会创建指向新状态的新工作流表示。转换可以建模为直接的或更复杂的涉及业务逻辑的定制,如您所说。 如果您使用函数式语言,您可以返回Monad来处理错误,但在这种情况下,您可以具体化并创建一个Monad,也可以抛出一个表示聚合消息的异常


希望能有帮助

你好@mbnx。你在哪里返回下一个状态?execute方法的实现不能,因为它返回通知。可以使用传递给execute方法的StateContext接口设置状态。我猜您在工作流对象中实现了状态模式,不是吗?下面的方法是实现转换的地方?
interface StateContext {
   setState(AbstractState state);
}

class AbstractState {
    abstract Notification execute(StateContext context);
}

class Task extends AggregateRoot implements StateContext {
    AbstractState currentState;

    ....

    public void start() {
        Notification n = currentState.execute(this);
        if (n.hasErrors()) {
            throw new Exception(n.toErrorReport());
        }
    }
}
class Task {

    private Workflow workflow;

    public void start() {
        workflow = workflow.followWith(Action.START, this);
    }

    public State currentState() {
        return workflow.state();
    }

    public List availableActions() {
        return workflow.nextActions();
    }

}