In Model-View-Presenter pattern where should we write validations of user input.
Domain specific rules/validations should be in the Model. You can have a model.validate() to let you know if the rules are not violated. Look at Rails model (ActiveRecord) classes for a good implementation of this concept.
The View should make it difficult for the user to key in invalid input. So 'entering a string for a numeric value' class of input errors should be nipped before reaching the presenter.
There may be some duplication of validations between model and view. E.g. AttributeX must range between 1-100. This must be validated in the model.. at the same time you may want to slot in a spinner in the UI with the minValue and maxValue range set to 1-100.
I usually keep my view completely clean, no logic there. But I don't do a lot of web development. In Ajax-ish situations you might want to have client side validation that has to go in the view.
Business logic validation goes in the model. With business logic validation I mean things like checking minimum order size etc.
Input validation goes in the presenter. This can be things like checking if a number field doesn't contain non numeric characters. But depending on your situation this can also mean checking if files exist etc.
In more complex cases where validation should be reusable in different places I usually separate it into a validation engine that can be called in different places. This solves some problems with duplicating validation code that is used in the presentation layer as well as the persistence layer for example.
Presenter....
The view should have have "widgets" that prevent invalid input where possible.
Related
I have been reading about specifications lately and I am really keen on using them. However, I am afraid to overdo it.
For example, if I have a User entity with a phone number property, do I need to put the phone number specification test in the setter, or is the validation logic in the setter enough?
Thanks,
Phil
UPDATE:
For more context:
I think I would like the validation to be in the domain, and not in the presentation. I will implement the validation in presentation, but that will be more of a UI feature. The idea (i believe) is that the domain cannot be in an invalid state, nor can it rely on the presentation. I actually have a phone number Entity, and many entities have phone numbers, though I suppose this could value object, but that is another debate:)
I was just wondering if it overkill to use Specifications in Property setters. One advantage I could see is that Specifications can be shared between layers, ie the Presentation Layer, so that you can share the validation code.
As you can see, I am unsure if this is the right approach.
Much Thanks,
Phil
You might look into the notion of pre and post conditions (invariants or design by contract).
Pre conditions are things that must be true for your function to operate correctly.
Post conditions are things that will be true when your function is complete and exits normally.
"user's phone number valid" is probably a good post condition to have for your setter function. However you have 2 choices for the pre-condition: (1) make it a precondition of your setter function that whatever is passed to it is valid, or (2) make a much looser pre condition to your setter function and perform the error checking in your setter function. Option (1) essentially passes responsibility for validation to the client. Option (2) endows your User entity with the responsibility for error handling.
I think the design you choose would depend on the bigger picture for your specific application.
Here are a few links for invariants and design by contract:
http://svengrand.blogspot.com/2008/11/preconditions-postconditions-invariants.html
http://en.wikibooks.org/wiki/Computer_Programming/Design_by_Contract
I often see people validating domain objects by creating rule objects which take in a delegate to perform the validation. Such as this example": http://www.codeproject.com/KB/cs/DelegateBusinessObjects.aspx
What I don't understand is how is this advantageous to say just making a method?
For example, in that particular article there is a method which creates delegates to check if the string is empty.
But is that not the same as simply having something like:
Bool validate()
{
Result = string.IsNullOrEmpty(name);
}
Why go through the trouble of making an object to hold the rule and defining the rule in a delegate when these rules are context sensitive and will likely not be shared. the exact same can be achieved with methods.
There are several reasons:
SRP - Single Responsibility Principle. An object should not be responsible for its own validation, it has its own responsibility and reasons to exist.
Additionally, when it comes to complex business rules, having them explicitly stated makes validation code easier to write and understand.
Business rules also tend to change quite a lot, more so than other domain objects, so separating them out helps with isolating the changes.
The example you have posted is too simple to benefit from a fully fledged validation object, but it is very handy one systems get large and validation rules become complex.
The obvious example here is a webapp: You fill in a form and click "submit". Some of your data is wrong. What happens?
Something throws an exception. Something (probably higher up) catches the exception and prints it (maybe you only catch UserInputInvalidExceptions, on the assumption that other exceptions should just be logged). You see the first thing that was wrong.
You write a validate() function. It says "no". What do you display to the user?
You write a validate() function which returns (or throws an exception with, or appends to) a list of messages. You display the messages... but wouldn't it be nice to group by field? Or to display it beside the field that was wrong? Do you use a list of tuple or a tuple of lists? How many lines do you want a rule to take up?
Encapsulating rules into an object lets you easily iterate over the rules and return the rules that were broken. You don't have to write boilerplate append-message-to-list code for every rule. You can stick broken rules next to the field that broke them.
From the limited amount of people that I've talked to regarding MVC web frameworks, I've heard people say that, forgetting about forms, a view file should ideally contain HTML markup, string manipulation and a few for each loops. I've also been told that if statements in views should be avoided if at all possible. Is this generally agreed?
EDIT:
The situation that has inspired this question is writing a navigation, I'm finding myself writing:
if secondary_navigation_item has children
...
I'm thinking, ideally, does this qualify as logic (that should not be here)?
Generally speaking, the View should not contain any server-side business logic. But it can still contain logic that directly pertains to rendering the view.
An example would be a view containing some sort of variant record, whose display depends on the setting of a particular field. For example, a record that displays different information depending on a sex field being set to male or female. Which, of course, would require an if statement.
To say that your views should not contain any conditional logic is just silly. How else would you generate UI elements like "new message" icons or flash messages—use a different view template for every possible interface state? It's like saying that your controller should not contain any variable assignments because data manipulation belongs in the model.
It's perfectly alright to have logic in your view as long as it's view-related logic. You shouldn't get caught up in absolutes or pedantic interpretations of the model-view-controller definitions. As long as you understand and apply the underlying concepts of MVC, you're on the right track.
Every rule has an exception, and there are cases where you would do string manipulating in a controller or even implement application flow in the view. Sometimes you just have to evaluate it on a case-by-case basis and apply a little common sense.
A view should basically contain:
HTML Markup
Javascript
CSS
Minimum of server-side code you may need to put into view
So, a View should typically contain the layout elements. The main processing logic should go in Controller.
More Info:
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
My company is developing a GUI application that allows users to query a legacy database system and have the results displayed back to them on the screen (the results just come back in a blob of plain-text). I'm struggling with the best way to structure the interaction between the user interface and the domain layer, especially validation of user input.
Basic Use Case
User selects a query to run from a menu in the application.
The application code displays the data entry form for the selected query.
The user enters the parameters for the query. If a field contains invalid data, it is immediately highlighted in red, and its tooltip text is changed to display an error message (i.e. if you are entering a Person query, and you enter a date of birth in the future, for example, the date of birth field will immediately turn red).
When the user clicks Run Query, the application runs a second validation pass; this second validation pass is required in order to run validation checks that involve multiple fields. If the this validation check passes, and all the fields are valid, the query is sent; otherwise, the user is prompted to fix any remaining errors.
My Current Validation/Error Reporting Strategy
Currently, I'm using domain-centric validation, but the overall design seems messy to me and maybe a little too over-engineered. A brief overview of the current design:
Domain layer: I have one class per query. Every query class contains a collection of IQueryField objects that hold the values entered by the user. Each query class implements a common IQueryMessage interface, which defines (among other things) a Validate method. This method is called to enforce message-level validation rules (i.e. rules that must examine the state of multiple fields at once). The IQueryField interface also defines a 'Valdate' method (among other things). This is to support per-field validation rules.
Per-field validation: To handle the per-field validation and error reporting, the data entry code binds each input control to an IQueryField; whenever the user changes the value of a control, it calls the the corresponding IQueryField's Validate method, which in turn fills a Notification object (just a collection of strings at the moment) with any errors detected in the value entered by the user. The user interface code then checks the Notification object and changes the appearance of the user control to indicate an error condition, if necessary.
Message-level validation: When the user tries to send a query, the application calls the Validate method on the IQueryMessage instance associated with the data entry form (at this point, the data binding code has also ensured all the message's fields have been populated from the input controls on the form, and the per-field validation code has been run). If there are any validation errors, the user interface displays them at the top of the form. If there are no errors, the data entry form is closed and the query is serialized and sent over the network.
Is Something Wrong Here?
I feel like something isn't "right" here. I have a few issues with the current design:
I would like the domain-level validation code to indicate the name of any fields that are in error, bur I don't want to hard-code the UI label captions into the domain classes. One possibility I thought of was to have the domain-level Validate methods generate messages with a field placeholder, such as "%s cannot be in the future", and have the UI code fill in the placeholder with the correct label.
The IQueryMessage and IQueryField interfaces both have a method called Validate. I'm thinking this should be extracted into a separate interface, (IValidatable perhaps), but I wonder if I am making things needlessly complex.
I'm using VB6, so I can't use inheritance in my classes (VB6 supports classes but not inheritance). I can only define and implement interfaces. Because of this, and because of the way my current interfaces are designed, I'm duplicating a lot of boiler-plate code in my implementation classes. I am thinking of solving this with an inversion-of-control approach. For example, I was thinking of defining a single concrete QueryField class, which could be initialized with a collection of IValidationRule instances that define what validation rules to use, then the QueryField.Validate() method would just collect the results of executing each rule. This way, the validation rules can be tailored to each field, but the QueryField class can handle all the common field-related stuff (field name, field length, required/not required checks, etc.).
How Can I Improve This?
I'm interested in any refactoring suggestions and hints on improving the current design. Also, I'm not necessary tied down to domain-centric validation; other suggestions are welcome. The main motivation behind using domain-centric validation was to keep increase encapsulation, and allow query message and field objects to be used in a non-GUI environment, without having to rewrite all the validation logic.
When you initialize a QueryField object, pass a label to it from the GUI. Then it's the UI that is responsible for setting the label name which seems reasonable to me.
I don't think this is necessary.
What you are describing doesn't really sound like IoC but rather just plain old composition. Since you can't even use inheritance this improvement seems to make sense. Generally you want to prefer composition to inheritance anyways. However if you are almost done with the work then I wouldn't bother refactoring this late in the game.
In coding a traditional MVC application, what is the best practice for coding server-side form validations? Does the code belong in the controller, or the model layer? And why?
From Wikipedia:
Model-view-controller (MVC) is an architectural pattern used in software engineering. Successful use of the pattern isolates business logic from user interface considerations, resulting in an application where it is easier to modify either the visual appearance of the application or the underlying business rules without affecting the other. In MVC, the model represents the information (the data) of the application and the business rules used to manipulate the data; the view corresponds to elements of the user interface such as text, checkbox items, and so forth; and the controller manages details involving the communication to the model of user actions such as keystrokes and mouse movements.
Thus, model - it holds the application and the business rules.
I completely agree with Josh. However you may create a kind of validation layer between Controller and Model so that most of syntactical validations can be carried out on data before it reaches to model.
For example,
The validation layer would validate the date format, amount format, mandatory fields, etc...
So that model would purely concentrate on business validations like x amount should be greater than y amount.
My experience with MVC thus far consists of entirely rails.
Rails does it's validation 100% in the Model.
For the most part this works very well. I'd say 9 out of 10 times it's all you need.
There are some areas however where what you're submitting from a form doesn't match up with your model properly. There may be some additional filtering/rearranging or so on.
The best way to solve these situations I've found is to create faux-model objects, which basically act like Model objects but map 1-to-1 with the form data. These faux-model objects don't actually save anything, they're just a bucket for the data with validations attached.
An example of such a thing (in rails) is ActiveForm
Once the data gets into those (and is valid) it's usually a pretty simple step to transfer it directly across to your actual models.
The basic syntax check should be in the control as it translates the user input for the model. The model needs to do the real data validation.