Sage 300 ERP Web UIs and MVC
We spent the last couple of blog posts talking about our new Sage 300 ERP (the product formally known as Sage ERP Accpac) server side programming framework and gave some examples. This week we are going to start turning our attention to the client side. We will be looking at how to structure the code in a UI form to create a well-structured Web Form, using SWT. We’ve refactored the client side SWT (Sage Web Toolkit) framework quite a bit since I wrote this blog post, so we’ll cover how that all works in detail over following blog posts.
Model-View-Controller (MVC) is a common design pattern in software architecture for designing UI programs. People tend to adopt the MVC design pattern, since it enforces some order on the creation of a UI program separating out the various parts into separate classes. This make the program more maintainable, but there are some other goals as well including allowing the UI look to be changed easier and to make the UI form easier to test.
In the diagram above, the dashed lines represent actions that happen directly from events, either from a user interaction with a control on the View or via something changing in the model perhaps due to receiving an SData data source event. Everyone draws this diagram a bit differently and no one really ever likes how data binding fits into this framework. But data binding is just too useful to do away with, so often the model is representing excluding any data binding. In some cases the model doesn’t generate events, but for us it does since changes in one part of the screen will generate changes for another through the model. So in a way this is the Sage 300 MVC design pattern.
We’ve adopted the MVC design pattern for all the new Sage 300 ERP Web Based UIs. We use the same design pattern for the main form as well as for popup forms. Within Sage 300 this gets a bit confusing since we use the name “View” for our business logic. However in this discussion a “View” has nothing to do with business logic and instead represents the actual visual part of the form with all its controls and such. The Model represents the Business Logic and is the part that communicates with the real Sage 300 Business Logic (in other discussions called Views).
There are quite a few other design patterns that are variations on this such as MPP, and several others. Sometimes the differences are subtle, but in our case we find it more convenient to stick with call it MVC model and frame things in regard to this. In a way our application programmers really program in a more MPP model, since all the direct communication between the View and Model is really handled by the SWT framework as part of our data binding support.
One of the key goals of these design patterns is to move as much code as possible away from the actual user interaction part. This is because testing user interaction is hard to unit test and requires specialized tools like Selenium to simulate real users pressing buttons and entering text. Anything that doesn’t directly interact with a user can be unit tested using regular tools like JUnit. Tests using JUnit are easier to include as part of the build process and so catch errors much quicker. So this approach allows much more of our code to be unit tested and facilitates test driven development.
Sage 300 View
Our View part of MVC is the declarative layout. This is the XML file that defines the form layout. This file defines all the controls, their layout and their CSS styles. We also provide a WidgetHelper class as part of SWT to simplify interacting with the controls on the form. The WidgetHelper class isolates the Controller code from having to check for controls being null (say because they were removed due to customization) and other details.
By keeping the View isolated from the other code, it makes it easier to replace the declarative layout either due to customization or due to special needs, like providing an iPhone version of a layout that is optimized for touch and small screen size.
Within our framework we have the ability for the View to create and define “Actions”. These actions can then be bound to the controls in the declarative layout. These actions are then the events of the View. This allows a greater level of customizability, since people can change the action that is called in the declarative layout to their own action to customize the behavior. Then the Action is the event that the controller receives rather than an underlying control event. So rather than the controller being notified of a button click, it’s notified of say a “save” action. This then further separates the details of the View from the controller (i.e. it isn’t tied to an exact specific control event).
Sage 300 Model
The Model manages the behavior and data of the application. It answers questions about its state and responds to requests to change its state. The Model encompasses the business logic, its state and the SData data source (including events). The model doesn’t just send data source events to the controller, rather it translates them into something higher level that is meaningful for the controller of this process.
We provide a couple of base Model classes in SWT that you can extend for your own applications needs. These base classes include support for interacting with the SData data sources and setting up the eventing mechanism.
Sage 300 Controller
The Controller responds to user and model events, informing the other to change as appropriate. Basically the Controller orchestrates the whole process and is usually responsible for creating and initializing everything as well as tearing down and releasing everything.
If things are written correctly then you can almost think of the controller as a workflow manager, which is controlling the workflow as things happen in the Model and the View.
When you press the “Ship All” button on the Order Entry screen, you would think it simply issues an SData service request to the server to call the Order Entry header view to process the request. However there is a bit of error checking first and then afterwards things need to be updated accordingly. Still this is about the simplest example there is, and can serve as a simple example of the MVC process.
Below is a UML process diagram showing, in gory detail, the whole “Ship All” process. The heading show the various components involved and whether they are part of the View, Model or Controller.
Keep in mind that many of the steps here are automatically handled either by GWT or SWT, so most of the application programming is in the ship-all controller to orchestrate the process between the View (User Interface Form) and the Model (wrapping the Order Entry SData feeds).
You might think that a screen only really requires one model or one controller. This is the case for many popup screen and many simple UI forms. However for larger screens like the main Order Entry screen this would lead to an extremely big model and controller. So conceptually we break down the main OE controller into many smaller controllers and similarly even though we have the main Order model, there can be many sub-models under this. Basically we don’t want our classes and objects getting too big. We want them all to stay maintainable and testable. We want to be able to work on one without breaking unrelated functionality elsewhere.
We also don’t want to create too big an MVC framework so that it requires a lot of boiler plate code to create these; we want the creation simple and if a part isn’t required in a certain situation, then it can be safely omitted entirely.
Hopefully this gives an idea of how we are using MVC as the model for our new Sage 300 ERP Web UIs. Perhaps this discussion is a bit theoretical at this point, but hopefully this will set the stage for looking at the mechanic of this in detail over some following posts and starting to look at some code.