In the model code we have to take care of
adding for every property of a class a check function that can be invoked for validating the constraints defined for the property, and a setter method that invokes the check function and is to be used for setting the value of the property,
performing validation before any data is saved.
In the user interface ("view") code we have to take care of
styling the user interface with CSS rules,
responsive validation on user input for providing immediate feedback to the user,
validation on form submission for preventing the submission of flawed data to the model layer.
For improving the break-down of the view code, we introduce a utility method (in
lib/util.js) that fills a
select form control with
option elements the contents of which is retrieved from an entity table
Book.instances. This method is used in the
setupUserInterface method of both the
updateBook and the
deleteBook use cases.
Checking the constraints in the user interface on user input is important for providing immediate feedback to the user. But it is not safe enough to perform constraint validation only in the user interface, because this could be circumvented in a distributed web application where the user interface runs in the web browser of a front-end device while the application's data is managed by a back-end component on a remote web server. Consequently, we need multiple constraint validation, first in the user interface on input (or on change) and on form submission, and subsequently in the model layer before saving/sending data to the persistent datastore. And in an application based on a DBMS we may also use a third round of validation before persistent storage by using the validation mechanisms of the DBMS. This is a must, when the application's database is shared with other apps.
Our solution to this multiple validation problem is to keep the constraint validation code in special check functions in the model classes and invoke these functions both in the user interface on user input and on form submission, as well as in the create and update data management methods of the model class via invoking the setters. Notice that referential integrity constraints (and other relationship constraints) may also be violated through a delete operation, but in our single-class example we don't have to consider this.