Reputation: 1213
Let's say I have a polygon class. Its only private data is an array of points. Should the class be written assuming the array has at least 3 points, and the GUI or input part of the program makes sure there are three points? Or should the member functions test the data validity and return an error message if needed?
Upvotes: 2
Views: 176
Reputation: 6526
There are some good points in the other answers. I'll try and state them here:
There are some challenges:
Here is what I like to do for complex validation:
ValidationError
that includes a human-readable description of a single validation error.getValidationErrors()
and isValid()
.isValid()
and getValidationErrors()
. If there are any validation errors, make the UI display the errors to the user. Prevent the user from continuing until the errors are fixed.The advantages of this approach are:
- More control of validation. You can decide when and what you want to validate.
- Centralizes validation logic in the model. The UI is only responsible for getting and displaying errors generated by the model.
- Less risk of other other code making invalid changes to a model if the model calls isValid()
before calling save/commit methods.
-No exception handlers.
Consider creating a ValidationRule
class. Each rule contains the code to valid something and generate an error message if it is invalid. The ValidationRule
class has a method validate(aModel)
. This is especially easy to do if your programming language supports closures or first-class functions.
This results in each model class can have a dynamic collection of ValidationRule
objects it consults when isValid()
or getValiationErrors()
is called. Alternatively, use a visitor pattern so that the models are are completely decoupled from the validation. This is what I do in my validation frameworks.
In a distributed application where the model is not on the client, it is often wise to do some basic validation before sending changes to the server. The round-trip time between client and server can be pretty long and you don't want to send obviously invalid requests to the server.
Lastly, the validity of one object sometimes depends on data in a different object! In these situations I let validation rules accept multiple objects, and use the controller object (or I create a context object) to manage the validation at a less granular level.
Upvotes: 2
Reputation: 497
If the class is expected to have at least 3 points you have to ensure it through the class interface. One way to achieve this (the only and best, actually) is receiving the polygon's points in the class constructor parameters and throw an exception if the points are less than 3 (remember that in a good OOP design, exceptions must not be seen as errors, but as a violation of implicit contracts). Then, you just have to keep unmodified the values of those points. Think as if they where "final" in Java. Remember that whatever makes your object a certain polygon amongst every conceivable possible polygon is never expected to be modified. For instance, if you assigned the points in the constructor, then those points should be preserved all through the object's lifecycle both in quantity and values. Always recall the most pure definition of object in OOP: an object is a computational representation of a real life entity. If your object represents polygon P, then it should never change in order to represent another polygon or any other real life entity. And you must never create an object "Polygon" if it actually doesn't represent a real world polygon. And that is achieved only through class constructors. Following these design guides, you'll never need to add code to validate your object is a polygon inside the Polygon class, since it is a true polygon in the object paradigm. So do the try {} catch {} when creating the polygon and let the constructor throw a NotPolygonException if needed.
Upvotes: 1
Reputation: 6781
IMHO, a well-designed class will always protect its invariants. Therefore, the class must validate and always ensure it's in a valid state.
The UI can do it too or just rely on the class.
Take a look at Mark Seemann's blog post here.
Upvotes: 1
Reputation: 22817
GUI validation is just meant for user hint.
Model should be responsible for its own integrity, as data may come from different sources rather than user [e.g. a background sync].
Upvotes: 1