msmani
msmani

Reputation: 720

DDD configurable contextual validation

We have an aggregate root named Document and a value object named Metadata. There are two types of Domain users i.e. "Data entry operators" and "Regular users". When "Data entry operators" create a Document 4 fields are mandatory out of 20 fields in Metadata but when "Regular Users" create a Document 10 fields are mandatory out of 20 fields in Metadata.

Class Document {
  Metadata metadata;
}

We could think of two solutions

  1. Create two separate value objects for "Data entry operators" and "Regular users" and let the value objects do the validation, themselves.

    Class OperatorMetadata extends Metadata {}

    Class UserMetadata extends Metadata {}

  2. Or, we could create a factory in the aggregate root Document and let it do the validation.

Is there any better way of doing this?

In addition to this, user may want the number of mandatory fields to be configurable, in that case the configuration comes from the DB, how to handle this scenario as well?

Upvotes: 1

Views: 252

Answers (1)

Joe
Joe

Reputation: 1357

You may be over complicating it with the inheritance approach. It also looks like some application specific concepts are leaking into your domain - is there really a concept of 'regular users' in your business domain for this system (there could be, but probably not as it doesn't sound like typical business language or concepts)

Think in terms of the business and not your program and ask "How does this entity come into existence?" For example, if the document belongs in some sort of audit-able document management registry you might use the term 'Lodge' for when someone (who? anyone? employees? specials?) decides to place a document under the control of the registry. This now tells us that we need at least 2 things - information about the person lodging the document, and information about the document as well.

If you are just new Document(params) them into existence you're missing out on the good bits of ddd. Expanding on the assumptions you can align your code to the business as follows.

class document {
  private document() {} 

  documentId Id {get; private set;}
  metadata MetaData {get; private set;}

  //even with no comments, the types and param names tell me lots about what this does
  public static document Lodge(person lodgedBy, metaData lodgementDetails) {
    if (ValidateMetaData(lodgedBy,lodgementDetails)) {
      return new document() {
        Id = documentId.Generate();
        MetaData = lodgementDetails;
      };
    } else {
       throw new domainExpceptions.InvalidLodgementException();
    }
  }
}

If the validation rules are dynamic ("may want" is a massive warning flag that your have not completed your preliminary analysis - stop coding now) then you have a new domain entity 'LodgementValidation'. You could include this in the lodge() parameters, move the lodge() routine to domain service class which orchestrates the now quite a complicate process of document creation or something else more in line with what is actually happen (It might be a purely application layer requirement for a specific UI - maybe the business rules actually don't care about the meta data)

I would recommend re-reading the published literature about DDD. It is more high level methodology and concepts than procedural instructions. Implementation details can and do vary greatly. Sort out your Ubiquitous Language and your Models then go from there; and remember Data Model != Domain Model != Application View Model

Upvotes: 1

Related Questions