Architecture Overview
Overview
hifive uses MVC architecture, illustrated here :
In Hifive we divide the client's components broadly into the following three layer
- View : Creation of view screen (in HTML)
- Controller : DOM manipulation, event handling, calling the logic layer
- Logic : Data transmission, database processing, calculation
Each layer is responsible for a specific kind of processing.
As a result of this division, you get two benefits. One is the increased productivity. Because the definitions file and structure of each process will be standardized, there will be no need to worry about how or where to write code. Another benefit, especially for large teams of developers working on one project, is that the code becomes much more easily maintainable and readable. Because of the standardized structure, you can easily understand the code when you do typically complicated tasks such as transferring a project to another member or team, reviewing code written by somebody else or maintaining the source code.
In each layer there is a lot of common and useful functionality that is automatically included at runtime, for example:
- View template engine
- UI block
- Library for asynchronous processing
This reduces the amount of separate declarations and allows for cleaner code.
The main design components in version 1.1 (current) and their roles are outlined below.
Controller
The controller is mainly responsible for event handling and view management. It can be declared hierarchically. By dividing a screen into its separate functions and assigning a controller to deal with each, the duty of each controller becomes more clear and the code is easier to divide into smaller blocks. Because of this, parallel development becomes easier for large groups and areas needing to be changed during project maintenance become clearer.
One of the characteristics of the Hifive controller is that it can be defined hierarchically .
By assigning a separate controller for each function the code required for each controller is lessened and maintainability is improved. It is also possible to divide the screen into a number of different spheres and give a separate controller responsibility for each. As a result, access to, or event handling of, elements outside of the controller range is avoided. Even with a complicated screen containing multiple controllers, unplanned actions can be prevented.
View
Views are written in HTML and CSS. On-screen contents will be updated by explicit operations from the controller or by the data binding mechanism (which we will talk about later).
With Hifive, we offer the following three types of view management:
- jQuery (general DOM manipulation)
- Used when manipulating a specific element (or group of elements).
By using the controller's $find() method it can acquire any jQuery object that descends from the element in the controller’s bind and that matches the given selector.
- Used when manipulating a specific element (or group of elements).
This system differs from using jQuery directly; the controller's zone of influence is limited to only descendants of the controller's binded element and hence there is no risk of accidentally manipulating elements outside of the controllers range.
- Template Engine
- This is used when the view will contain complicated tag structures. The tag structure generated when using jQuery alone can be difficult to understand. If the view is generated from somewhere in the business logic code, it will be difficult to know from where exactly the view is being manipulated and to recognize clearly the zone of influence when you want to do maintenance.
However, if the view creation is left to the template engine, tag structure will be easy to understand and it will be clear where and what must be altered to update or change the code. With Hifive we use EJS, a template engine that allows JSP-like coding.
- Data Binding (Introduced in ver.1.1)
- Data binding is an arrangement that should be considered for views that will be frequently updated.
In this system, you must describe the relation "The value for on-screen element X is linked to property Z for data object Y" in the view. Then when the DataItem (each representing a record in the data model) and the ObservableItem (the temporary form of the DataItem) are changed, their change events are detected and the linked view is automatically updated.
- Data binding is an arrangement that should be considered for views that will be frequently updated.
Because data changes are automatically reflected on screen the developer doesn't have to worry about DOM manipulation with jQuery. The developer can then concentrate on the data processing side and view and logic can be clearly separated.
Another feature of data binding is that changes to one data object can be reflected simultaneously in multiple elements. Thanks to this, keeping multiple on-screen components in a consistent state becomes much simpler.
Logic
In Hifive we interpret logic to mean "processing", for example:
- Complicated processing
- Communication with the server
- Local Database processing
(View manipulation or event handling are not dealt with)
By being careful to only include "processing" code we can expect the following merits:
- Improved readability -> It becomes easier to trace processing
- Improved re-usability -> No need be concerned with view output
- Easier testing -> By using the unit testing tool it becomes easier to run tests
- Improved maintainability -> There is no need deal directly with the JavaScript used when changing appearance
When making amendments to the logic you shouldn't have to worry about how the view is implemented (HTML structure etc.)
The logic layer defines processing, communication with the server and so on.
This layer is especially useful for defining processing that is common to multiple screens (controllers). By using JavaScript at browser runtime it is possible to manipulate the view from the logic layer, but by taking care not to include any direct view manipulation it will be *easier to reuse the code and do unit testing.
Applications using HTML5 rely on a variety of client APIs, so, depending on the application, sufficient unit testing will be demanded by the client. With this in mind, we recommend keeping all your complex logic code separate to make testing simpler.
Data Model
The data model is the layer responsible for data control. By passing a schema to the data model, it can check validity of, and impose restrictions on, data. JavaScript allows you to set any arbitrary key value pair. However, without limitations on object properties it can become difficult to spot bugs if the data structure changes during programming or after maintenance.
The Hifive data model uses a predefined schema for each model, similar to many DBMS.
By doing this, the values of the object (which represents a record in the RDBMS) can be accessed using the get() and set() methods. If any keys which are not defined in the schema are assigned, an error will be thrown. The schema is not just for defining the type of variables, but also putting limitations on them, for example "only values from 1-10" or "not an empty string".
Also, the model allows for declaring the dependent calculation property. For example, if property X is given the "dependent calculation on S" property, when S changes a function to automatically recalculate X will be called. The value returned from that function will be newly assigned to X and saved by the framework until S is reassigned a new value.
Furthermore, the data model in hifive includes a mechanism for alerting the exterior of data object additions, deletions or changes. One of hifive's three view types, the data binding mechanism, supports this functionality; by simply altering the data model any changes will be reflected on screen. The full power of this is most apparent in tasks such as displaying repetitive data (e.g. lists) and the developer can focus on writing code.
AOP for Controller / Logic
The controller and logic layers of Hifive adopt the aspect-oriented programming (AOP) paradigm. To be more specific, it is possible to set up an interceptor (method hook) before calling any of the controller / logic methods. It is thereby possibly to start any event handler logging or execution timing code in just one place.
Unfortunately performance related problems are often realized during the middle or final stages of development, and we're prone to just sticking something like :
doSomething();
var end = new Date();
alert(end - start);
inside a function that seems problematic.
In situations such as this, by using AOP you can measure execution time without having to rewrite the code.