Faced with a clean slate, many application architects take yet another look at the model-view-controller (MVC) pattern to veer off the evils of a bad foundation. Even those architects that choose ready to use frameworks tend to measure these against concepts coupled with MVC. Of MVC itself many variants and interpretations exist, but I think the general idea idea is to divorce the "model" from the "view" (UI). The "controller" part is the artifact that is needed to manage the possibly complex interaction between the two. MVC regards the UI is as the presenter of information and as the initiator of many actions.
In many real world applications, the idea of "present" and "initiate" is well understood and makes up a small part of the code. A lot of the code lies in the "capture" and "store" of the information. In these applications, the complexity tend to revolve around the validation rules that facilitates data capture. Vanilla MVC does not address this issue in specific detail. Sometimes it is incorrectly assumed that validation happens on the "view" side of the MVC triad.
Recent developments on the domain driven design front also tend to suffer from this weakness. There seems to be a lack of a ubiquitous approach to validation. As you elaborate that domain model of yours you write unit test, you would conclude that many tests are about validation rules of some kind. Hence, the quality of an implemented domain model must be directly related to its ability to prevent invalid data from entering the system.
"Garbage-in, garbage-out" is a mantra repeated reverently when facing a scenario where some poor sod used an application incorrectly. Bah! "Garbage-in" was the fault of the developer. Instead of blaming the sod, we should promote him to the test team!
Values are supplied not only via user interfaces, but also by web services, data imports, queue processors and who knows what other ways. Consequently, field validation cannot be an issue that is simply shunted to the user interface level. Using MVC parlance: validation cannot be in the "view"; it has to be in the "model".
Key to your design must be the idea that a validation rule is written once and only once. Wherever a value governed by this rule enters the domain, the rule shall be applied. Non- conformance to the rule leads ultimately to the rejection of the change.
Why not simply throw an exception on the setter when an invalid value is given? The biggest problem with this approach is that the UI code (quite possibly your most important client) becomes bloated with exception handling blocks. It uses these blocks to try the translation of the cryptic exception thrown by the domain library into a meaningful error message. Mostly it fails - the message becomes irrelevant and the user is not helped. In fact he is agitated by such messages.
The exception throwing plan has more problems. Some validation rules apply to a combination of values (e.g. a rule that ensures the birth date and ID number should coincide), or require other objects to be validated (e.g. the ID number must be unique). On which setter do you throw these exception?
An alternative is to allow an instance of a class to be invalid at any given point in time. Such an object would have a set of validation rules that have been breached. Each rule is associated with the appropriate message text. This text is presented to the user. Keep in mind the user interface is responsible to present the error messages to the user. An exception occurs when the client tries to commit an invalid object (to storage or for further processing).
Many details remain to be sussed out. The message in this blog is in the shell of a nut: Do not throw up, invalid domain objects are cool!
Sunday, March 14, 2010
Subscribe to:
Post Comments (Atom)
Mmm, hierdie topic lui 'n klokkie :P
ReplyDeleteGood blog ... more please :)
ReplyDelete