Thu Jan 15, 2004 2:17 pm
All,
How are business rules handled in a DDD? Do you throw errors (like
a BusinessRuleException) from all the methods which contain business
rules? How are those errors exposed/propogated to the client?
Lets take the Cargo Shipping System mentioned in chapter 7 as an
example. Say I had a business rule that states that Cargo could not
exceed 10 lbs in weight. Some user attempts to enter cargo wich
exceeds this weight.
Where would this business rule be located? If it were violated, by
what means should it be exposed/propogated to the client?
Regards,
Joshua
In my view, one responsibility of domain objects is to be able to validate
themselves - validate that they are in an acceptable state. Therefore my
preference is to have domain objects implement a set of methods that perform the
validation (i.e. encode the business rules). In my framework these methods are
invoked at the appropriate events in the object's lifecycle (typically, when the
object is about to be persistently created or persistently updated). If
validation fails, feedback is given to the user, else the persistence operation
proceeds. I much prefer this to throwing exceptions out of setter methods, for
a variety of reasons. First, you want to be able to apply all of a user's edits
to a domain object, and then ask it to validate itself. Second, those throws
exception clauses would (needlessly and painfully) propagate through the
codebase (at least in Java) if you did it that way.
See also
http://c2.com/cgi/wiki?DomainObject (which was written before Eric's
book)
and
http://c2.com/cgi/wiki?ExceptionPatterns (specifically,
http://c2.com/cgi/wiki?LetExceptionsPropagate)
RandyStafford
> Lets take the Cargo Shipping System mentioned in chapter 7 as an
> example. Say I had a business rule that states that Cargo could
not
> exceed 10 lbs in weight. Some user attempts to enter cargo wich
> exceeds this weight.
> ...
> If it were violated, by
> what means should it be exposed/propogated to the client?
My answer would be: As early as possible. This means that the GUI
should never let the user enter a greater weight than 10 lbs.
How did I figure out that? Well, I didn't. People at Toyota did it in
the 60's and called it poka-yoke: Defects in a process should be
eliminated as early as possible.
Where to place the business rule? Of course, the GUI should ask the
domain layer for any constraints. I cannot speak for DDD how to
represent the rule in the domain model.
JohanNilsson
I aggee. Defering this until transaction commit may have led the user down a path that created lots of unnecessary cascaded errors. By detecting it early, we help prevent the user from making other errors, or doing a lot of useless work based on incorrect assumptions.
JimAmsden
> My answer would be: As early as possible. This means that the GUI
> should never let the user enter a greater weight than 10 lbs.
I find that the answer is usually twofold -- on the one hand, you want
you interfaces to constrain the possible user activity to valid
behavior as much as possible, but on the other hand, when you have an
enterprise system with a database in the picture, you usually really
really want (or at least, your DBA team usually really really wants) to
ensure that things can't somehow go wrong up at the application layer
and end up corrupting the integrity of the database. This is because in
a multi-application environment, other apps may make assumptions about
the data in the database, and you don't want one of your apps to be
able to store data that violates these assumptions.
So, this feeds back to the exception dialog a bit -- I find that a good
balance is usually to do early validation at the application tier, and
data-write-time validation / consistency checking at the database tier.
The application-level validation is where the expected paths of
behavior will exist, so you should never get a consistency failure from
the database tier. But if you do, then the application's validation
capabilities have failed, so this is truly an exceptional circumstance,
in that the database-level consistency check is checking the behavior
of the *application*, whereas the application-level consistency check
is checking the behavior of the user. As we all know, users can be
forgiven for inputting incorrect information, but your application
should know better.
Bear in mind that your technology choices will very likely have an
impact on how early you can do application validation. For example, in
a pure-HTML servlet-based app, it might make sense to put validation
logic into your domain model, and providing it an opportunity to do a
consistency check after any request parameters have been loaded from
the HTTP transport layer into the domain model. But if your
presentation technologies allow for earlier validation, then all the
better. Swing validation, for example, can certainly happen at the
widget layer, and many web app programming frameworks provide some
concept of validation at the input or request level that happens before
the business logic is invoked.
PatrickLinskey
Are there any patterns for implementing business rules in a DDD? I
have only read the first couple chapters of Eric's book. So far, it
doesn't seem to focus in this area. (Again, I haven't read the
whole thing).
Any suggestions?
Regards,
Joshua
>Are there any patterns for implementing business rules in a DDD?
See Chapter 9, especially the "Specification" pattern. There's also
some discussion at the end of Chapter 3, in the section "Modeling
Paradigms" (pp. 116-122).
JohnBrewer
Patrick,
I tend to agree with you on pushing validation close to the UI layer. However, arent Domain models supposed to encapsulate all of this behavior?
Several patterns/desigh books have advocated that the business rules should exist in the domain layer. Unfortunately, they do not suggest any patterns for implementing them or provide any further detail.
Eric, where do you put your business rules?
Regards,
Joshua
none none <gemini929@s...>
> Several patterns/design books have advocated that the business
rules should exist in the domain layer. Unfortunately, they do not
suggest any patterns for implementing them or provide any further
detail.
The observer pattern certainly should play some part if the business
rule concerns more than one object.
If we look around, constraints in UML are expressed using the Object
Constraint Language (OCL).
"All normal elephants have four legs":
Elephant->select( isNormal ).legs->size = 4
If we were to implement OCL, we would probably represent a constraint
as an object. In order to validate the rule, the constraint object
would have to observe all instances of classes that are involved in
the expression.
As soon as we touch any leg...
jumbo.legs[0].Delete
... some CanDelete event is fired for the Leg instance. The
constraint object will be notified and the rule expression can be
revaluated.
JohanNilsson
DomainObjectsAndBusinessRules is mentioned on: ThreadView