o you ever feel like you're beating your head against a wall?
I know I do; quite often, in fact. It seems like developers spend half their time bending technology to their purposes when the technology doesn't really quite fit. Well, I'm actually thinking of one problem in particular right nowvalidation. Can you think of a more boring topic? There are a few, but I think you can agree that it is an extremely important one in business software.
And yet it plagues us and has plagued us for years and years. Why? Because we've been thinking about it all wrong, or at least partially wrong-enough wrong to be a pain in the behind. The pain all started with the grand idea that validation should be done in the database schema; that truth statements about the validity of data are always true.
I can think of two problems with the traditional approach to data validation. First is that it resides in the wrong layer(s) in the application (that is, in the database or, worse, the UI). Second is the aforementioned error that there is one valid schema for a set of data.
Putting Validation in its Proper Place
I've said it before, and I'll say it again: business applications are about automating processes. Too often, we think in terms of the data that we're dealing with, but data is important only in as much as it supports the process that we're trying to automate. So what does that tell us about the proper place of data validation?
|Business application development has come a long way and made a lot of important advances in recent years, both in architectural approaches and tooling, but we can and should still build upon these to better address the business processes we are attempting to automate.
You guessed it! Data validation should occur as part of the process in which it participates. But you ask: "What does that mean? After all, I've got some data validation occurring on my form, some in my business layer, and some final validation (via constraints) in my database. If my application is automating a process, and I've got validation sprinkled throughout that process, isn't my validation already occurring in my process?"
Okay, now you're being clevertoo clever for your own good. Yes, I'll be the first to say that even something as simple as directly updating a record is a process (or a workflow, if you prefer). Process is everywhere in a business, and our applications participate in it even when we don't think about it per se. But my point is that we need to be thinking about everything our applications do as part of a process.
|Business applications are about automating processes.|
Once we do that, we'll start thinking about the various pieces of our application in a way that makes good business sense. I'm talking about reducing the impedance mismatch (to steal a term from the object-relational mapping world) between how we think about designing our applications and how businesses think about what they do.
Good object-oriented design will take us far. Domain-driven design goes a bit further, and service orientation can help us in the long run. But we need to realize that the underlying domain in business software is process-centric, and we need to start aligning our design with the business domain.
But what does this mean in terms of validation? It means that a set of data is valid only when it intersects with a point in a process. Therefore, our validation schemas should not only specify constraints and rules but they should also be linked to a point in the data's lifetime. It means that we can't design our constraints and rules in the database, nor should we stuff them into the UI tier, at least not directly. In fact, we probably shouldn't even put them in our business tier or domain model per se.
Rather, data validation should be a separate layer, a serviceone that we can ask at any given point in a process: "Is this data valid right now?" Again, this implies that our constraints and rules tie themselves explicitly to data lifetime, so we need frameworks and tools that support this.
As it stands today, the best toolset and framework I've seen that could support an approach like this (apart from writing a custom one, of course) is Windows Workflow Foundation (WF). It has a built-in rules engine, and it has explicit support for state-based workflows (a.k.a., state machine workflows). It is very extensible, and it is being advocated strongly by the biggest software vendor in the world as part of their foundational technologies for the future.
This article really isn't about WF, though. Perhaps in a future article, I or someone similarly inspired will create a working solution in WF that does what I'm suggesting, namely, joining business rules (including constraints, which I think of as part of business rules) and state machine workflow in such a way that a client can query the workflow to determine if the related data is valid in its current state, the state being the delimiter in the data's lifetime in which validation rules can be inhered.
Hopefully, you can imagine how you can still have a domain model, with all its behavior-based objects that participate on a more finely grained level in the overall process. For instance, one of the domain object's methods might move the object (and related objects) from one state in a workflow to another and, in the process (no pun intended), ask the workflow if it is valid in the new state.
With such an approach, you more closely mirror the truth of business processes, namely that data validity is point-in-process-sensitive.