A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.
I'm having a conceptual problem in the intersection of OO, the MVC pattern and validation. In short. I have no idea where to put validation and how to apply it.
In principle we should only allow objects to be in a valid state any time. If I contruct an object is should be valid at contruction time i.e. I should not pass malformed data to the contructor. If a constructor gets invalid information is should throw an exception.
Since my program interfaces with the real world I can expect malformed data from the user, so I have to add validation somewhere. It shouldn't be in the contructor as malformed data isn't exceptional, so it has to be somewhere before it.
In the MVC pattern, the view shouldn't ever know about validation and as just explained I can't argue for putting the validation in the model. I don't like putting validation code in the controller, but I don't see how it could be moved away.
Maybe I could make some MVCV pattern and get the validation put in some other place where the coupling to the controller is smaller. How would you go about doing this? Would you create some static validation classes with helper functions invoked by the controller, or how do you go about it?
I'm really perplexed. Thanks in advance.
The MVC pattern attempts to impose some structure, but the "barriers" b/w the various roles in an application are not always so rigidly enforced. It all depends on how you slice your application up - physically, by objects, role in a pattern, by aspects, etc. In the real world, strict layering rules are often violated in order to optimize for performance or for other practical reasons. Also, correct me if I'm wrong but MVC doesn't say anything specific about input validation.
It seems to me that each layer is responsible for some validation. Your model objects should not accept bogus arguments. That's why there is an IllegalArgumentException in Java. Some IOC containers also define callback methods that your model object can use to raise an exception if an object has null properties.
One could argue that these routines are really part of the Controller. OK, so the Controller is distributed across physical tiers and multiple program components.
What if I put all my data validation rules in XML files that are indexed by "action"? Are they part of the Model, View or Controller? The Controller invokes this validation logic in response to a request, but is it considered part of the Controller?
In the past, I have hard-coded validation routines in a web "Controller" class. Many of these are static routines and could just as easiy be placed in separate libraries.
Saturday, June 17, 2006
It's not always necessary to make a call to the server to validate input. Some things can be encoded as static rules and need no state information whatsoever from the server. I can think of numerous examples:
- empty fields
- malformed email addresses
- field must be a certain number of char's long
To call a routine on the server in these cases is an unnecessary use of network/server resources. Further, to add checks for all these special cases in your server when they already are performed on the client is unnecessarily redundant.
HTTP/XML-based remoting (AJAX) or traditional request-response could be used to talk to a routine on the server in order to validate against a database. Things like:
- Invalid address (wrong zip code)
- A user with that email address already exists
- Wrong password
The principle here is that each layer only talks to the next layer if it needs the information.
But, I think the confusion arises by considering the M, V, and C to be distinct physically distributed layers/tiers, when in fact M, V, and C functionality can be distributed and overlap multiple tiers. Validation can be performed in multiple places.
Well unless you want a security hole the size of Texas you _always_ have to do validation on the server side of anything that is submitted by the client, without which it is a trivial matter for a hostile client to submit invalid and potentially dangerous data.
Whether this server side validation is user friendly or solely to prevent dangerous data from fake or buggy clients, with additional friendly validation clientside, is another matter.
The issue with relying on 100% server side validation is one of performance. Doing client side validation can give the user much quicker feedback about errors they may have made in input, the problem here is the the client needs to know what is and isnt valid input, and much of this is a function of the business rules that form part of the model, and often requires the validator to be able to retrieve information from the database.
This can be aided by having the model provide the controller & view with additional metainfo about fields beyond just the data types (where such info is static in nature and not dependent on the result of runtime business logic) such as minimum and maximum values, regexps for valid formats, and so forth.
Java GUI Programmer
Sunday, June 18, 2006
I have built a framework based on MVC and IMHO the best place to put validation is in the model, never the view or controller. Validation is, after all, the implementation of business rules, and all busness rules should be contained within the model.
In my framework all views are supplied from reusable XSL stylesheets which do not contain any hard-coded references to any database table or column names. All my controllers are reusable which again do not contain any hard-coded references to any database table or column names. Hence these two components do not know what data they are dealing with and are therefore incapable of validating it. All this knowledge resides in the model, so it's the model's responsibility to validate the data before sending it to the database.
Sunday, June 18, 2006
What you can do is. Create Validator object within your Model, and let Model to provide Validator for the UI. Then your UI can ask Model for Validator, talk with validator using user input, and display appropriate messages to the user.
This way, you will keep your UI away from knowledge on validation process. I described how I did it here: http://blogoforum.com/tag/design+development+mvc+oo+validation/where-to-put-validation-in-mvc-1311.html
Sunday, June 18, 2006
> Once and only once.
A better form of OAOO is to define the validation in one place and use code generation to implement validation at every relevant layer.
You want as much validation as possible closest to the user so they have a good experience, yet as each of the layers are independent they need to validate too. But implementing them independently leads to a nightmare of inconsistencies.
That's why I like the generation approach. You define once but implement everywhere from one definition.
son of parnas
Sunday, June 18, 2006
Smart objects or dumb objects? In MVC the model is like a combined business and data object, so it needs to be smart enough not to persist invalid data.
So there's going to be "pain," and as one post suggested code generation can be used to ease the suffering. ;)
If the body of business rules is large and/or complex, it may be helpful to encapsulate validation in another layer which must be called from the model layer before saving.
I'm not a big fan of having the M throwing exceptions on bad data, IMO exceptions should only be thrown on exception circumstances and sadly bad data isn't.
The approach we have is to allow the business object (M) to keep the bad data but to all contain the list of currently broken business rules. As properties are changed this list has items added and removed. This solves the problem of two properties dependent on each other for validation.
The business objects are built on top of an OR Mapping system that will throw an exception if an invalid object is committed to the database.
This allows our M to define all the rules as well as provide some good feedback.
Who says the Model has to throw exceptions when it encounters bad data? That's not what exceptions are for.
In my framework the Model generates an array of errors, and if this array is not empty it does not waste time trying to write anything to the database. When the Controller receives the result of the Model's efforts it notices that the error array is not empty so it instructs the View to rebuild the page with the error messages (yes, there can be ore than one!) inserted in the right places. If the error array is empty then the Controller moves on to the mext action.
Wednesday, June 21, 2006
hehe, something like this? ;-)
* Thrown when the user enters a value that is actually
* correct and meaningful. This situation is so unlikely
* that we dont even make this a checked exception as its
* doubtful anyone could implement code to handle it.
public class ValidInputException extends RuntimeException
Java GUI Programmer
Monday, June 26, 2006
This topic is archived. No further replies will be accepted.Other recent topics
Powered by FogBugz