Question

DDD was chosen as an architectural pattern to tame a wild database model, as well as ubiquitous language. However, there is a sticky part of our model -- many of the rules are dynamic, and I don't know how to reconcile them with what I understand of DDD.

class Account {
    private Mailing[] mailings;

    void SubscribeToMailing(Mailing m) {
        if (/* this is allowed */) {
            mailings.Add(m);
        }
    }
}

The problem I am encountering is that the "this is allowed" check must be determined at runtime. There are conditional rules the system can be configured for. It makes sense to me to check these in a service, because the service can get a rule check injected into it. But, to do that would drive me towards an anemic domain model, which I've been led to believe Is A Bad Thing.

Where should these runtime checks happen?

edit for more clarification:

The product is multi-tenant, so "one size fits all" does not necessarily apply. The tenants are across multiple industries, so industry-specific rulesets cannot even be baked in there. There are known hooks in the system that configuration can happen, and that is the language we are trying to capture.

Rulesets could be something like "this product costs $5.35 each, unless the account is in this role, in which case the product costs $5.15 each". The roles are created by the tenants, the product pricing is created by the tenant, and even the decision to apply different pricing at all is created by the tenant.

Était-ce utile?

La solution

Where should these runtime checks happen?

If it is domain logic, then the checks should happen inside the domain model. If it is application logic, then the checks should happen in the application code.


If it is domain logic, and the configured information isn't copied into the data structure of the domain entity, then that configuration information would be passed to the domain model as an argument.

Autres conseils

DDD as practiced today by most, and described by most resources online and offline is about anemic models. The most I've seen people do is to have some trivial methods which work in complete isolation in the "domain objects" themselves, but that is basically it. For anything more there are "Services".

Just to be clear, there is a spectrum from anemic to rich objects. The more "Services" you have the more anemic your objects become, since you are taking behavior away from your model. In a completely "rich" object model there are no services whatsoever, and in a completely anemic model there are no methods in the "model" other than setters/getters.

So in short, if you want to have "rich" objects (i.e. with real behavior) you can not have DDD, or have to significantly re-interpret what DDD is.

Licencié sous: CC-BY-SA avec attribution
scroll top