1

Does it make sense to create a field in ValueObject as an interface?

I have a field in my aggregate that represents its status. The state has a natural event-driven flow, but there are times where the state can be set manually.

Currently I have an enum which we treat as a VO, and this contains the flow logic and whether it can change to one state or another.

public enum State{
  OK,
  KO,
  PENDING(List.of(KO, OK)),
  CREATED(List.of(KO, PENDING))

  private final List<State> canGoStatus;

  public boolean canGo(Status status){
     return canGoStatus.contains(status)
  }
}

The manual update has a number of validations, e.g. from which status it can be set and only a number of statuses are possible, in this case, an OK status cannot be set manually.

As the manually update is a new feature, I was thinking of migrating this VO to a class with a field as an interface, which would be implemented by one enum for the normal flow and one for the manually flow.

public interface IState{
  String value();
  boolean canGo(IState status);
}

public enum EventDriveState implements IState{
  OK,
  KO,
  PENDING(List.of(KO, OK)),
  CREATED(List.of(KO, PENDING))

  private final List<EventDriveState> canGoStatus;

  public boolean canGo(EventDriveState status){
     return canGoStatus.contains(status)
  }
}

public enum ManuallyState implements IState{
  CANCEL(List.of(EventDriveState.PENDING, EventDriveState.CREATED)),
  REGISTERED(List.of(EventDriveState.OK)),

  private final List<IState> canGoFromStatus;

  public boolean canGo(IState status){
     return canGoFromStatus.contains(status)
  }
}

So I can encapsulate this business logic in the domain, and from the VO itself, generate one implementation or the other, separating in two use cases the two updates (e.g. ManuallySetState, EventDriveSetState).

public class State{
  private final IState state;

  public boolean canGo(IState state){
   return state.canGo(state);
  }

  public static IState manuallyState(String state){
    return ManuallyState.valueOf(state)
  }

  public static IState eventDriveState(String state){
    return EventDriveState.valueOf(state)
  }
    
}

I'm just starting out and I don't know if this is the purpose of DDD.

Mr. Lennon
  • 11
  • 3

0 Answers0