RIF Architecture: Presentation Layer

by Kevin Garwood

In the architecture, the presentation layer is broken up into a number of client applications which access the database via service interfaces. Although we anticipated that the study submission tool would eventually be implemented as a web application, we decided that it would be useful to first build a simpler desktop version of the tool. There were three main reasons for developing the desktop version that had planned, short-term obsolescence:

A design that anticipates and invites substitution of front-ends should not include business-critical logic in them. In particular, if we anticipate that a desktop application may be replaced by a web-based application, we should not assume the front end will do any validation of form data. The safest assumption is that the presentation layer will limit possible combinations of inputs through guided data entry. However, validation should be done by the business and data storage layers. Furthermore, whereas a front end should eliminate scenarios for how input data should be used with services, the services should anticipate any scenario for how the input data could be used.

Validation-1 : Assume the client applications will do no validation. Validation code will be distributed between the business concept and data storage layers of the architecture.

Code used to generate GUIs can become very repetitive and can incur a significant maintenance cost. There are three ways that presentation code can be simplified. First, all the pieces of text that are visible to the user through labels, buttons, lists and error dialogs should be retrieved from a properties file instead of hard coded in the GUI code. Using a property file, the messages can be changed without having to recompile the code. With only little instruction, it is possible to have a non-technical people proof-read the properties file without requiring effort by developers. Furthermore, these non-technical people can be used to craft versions of the properties file in other languages.

Maintenance-1 : Maintain the text for all GUI components and text for error messages in a properties file.

Second, code used to instantiate and initialise Java Swing components should be consolidated within a factory class. The class rifGenericUILibrary.UserInterfaceFactory serves this purpose and is meant to minimise the amount of repetitive code used to create simple Swing-based GUI widgets. The factory also makes it possible to customise the look and feel of GUI components for individual tools running within the same Java Virtual Machine.

Maintenance-2 : Centralise code for creating and initialising Java Swing components in a single factory class.

Third, create classes for common user interface displays. For example, rifGenericUILibrary.OKClosePanel is a general-purpose class that creates a common panel of buttons which appears in the lower-right corner of most dialogs. Creating this class reduces repetitive code while helping to standardise the way "OK" and "Close" buttons appear in dialogs throughout a tool.

Fourth, isolate common UI classes into a sub-project that does not depend on RIF-specific concepts. Initially, we created classes the created UI components that were repeated throughout the desktop version of study submission tool. However, as we began to develop the Data Loader Tool, it became clear that the same classes would be reused in other sub-projects as well. Therefore, we decided to isolate a small sub-project that was as independent of the rest of the RIF code base as possible.

Maintenance-3 : Create classes that render user interface features that appear across multiple tools. Isolate these classes into a sub-project that shows no dependencies on classes that relate specifically to the RIF.

Fifth, wherever possible, GUI classes should avoid inheritance from other Swing classes. The main reason for this decision is that in most cases there is no need to take advantage of methods in the Swing super classes and inheriting from these classes can complicate the generated JavaDocs. It is better to create a class that contains an instance of a JDialog rather than extends one. The intent of the class and its role in the code base becomes clearer.

Maintenance-4 : Contain rather than inherit from GUI classes.

The main exception for this convention is the practice of extending javax.swing.AbstractTableModel, which is designed to support common implementations of the TableModel interface.

Coding Conventions

Coding conventions for this layer are described here.