Over a million developers have joined DZone.
Platinum Partner

Is MVC Pattern a Dead End for Application Development?

· Java Zone

The Java Zone is brought to you in partnership with ZeroTurnaround. Discover how you can skip the build and redeploy process by using JRebel by ZeroTurnaround.

In this article I would like to show you why using MVC pattern is not enough to be able to create agile and scalable applications. I will also suggest possible solutions to identified problems.

In the Model View Controller pattern nothing is wrong. It solves the problem it was invented for – to divide user request processing logic from presentation logic.

Before this pattern was invented, user request processing logic and presentation logic had been tightly-coupled together in one file. It made maintenance much more complicated and led to a number of bugs in the system.

MVC pattern is a good choice when application modules are more or less independent from each other.  For instance, they are called from the main menu.  Let’s imagine that to finish up the business process we need to pass step by step modules:  A. B, C, D. Entity created in module A becomes available in module B. Entity created in module B as well as entity created in module A become available in module C, etc.

In this case, the user should know the order of how to work with system modules to be able to make the necessary changes. Also, if the process of work with the system has changed (business or domain model has changed) the user can adjust to the new process with no changes in user interface.

Everything is fine until the system is used by a small number of people when it is still not a problem to train them in how to use it.  What about the system delivering to a great number of users?

In this case to simplify the work application should know how to work with it and lead the user through the system step by step opening up the further steps.

But here lies the cunning use of MVC pattern. As you can see from image below it is tempting to refer from module ‘A’  presentation(View) directly to module ‘B’ controller (Controller), from module ‘B’ to module ‘C’, from module ‘C’ to ‘D’, etc.  

(Or from controller of module ‘A’ to controller of module ‘B’. Or even worse from controller of module ‘A’ to presentation (View) of module ‘B’)

Business process will be tightly sewn in 3 views. I agree that it is a bit confusing. Since relationships are distributed across multiple files - to change business processes will be cumbersome.

And you have to hard-code business logic within if/else statements to be able to support different variations of A, B, C, D.  Unfortunately such approach is quite often used to build up applications.

How to return former loose coupling to system modules but to retain described business processes inside.

For this purpose you need to move configuration of business processes out of modules and place them separately. To ensure that users and all modules communicate via one Root or Front Controller. In this case controller will take from configuration what modules in what order to provide the user with. Modules will communicate through root controller by means of events to provide the loose coupling approach. 

Configuration of some basic flow can look like:

<?xml version="1.0"?>
<application initial="A">
    <module id="A">
        <on event="next" to="B"/>
<module id="B" >
<on event="previous" to="A"/> <on event="next" to="C"/> </module>
<module id="C">
<on event="previous" to="B"/> <on event="next" to="D"/> </module>
<module id="D">
<on event="previous" to="C"/> <on event="finish" to="finish"/> </module>
<on event="cancel" to="cancel"/> <final id="finish" /> <final id="cancel" /> </application>

In this case is quite easy to change system behavior just by removing some steps from the configuration:

<?xml version="1.0"?>
<application initial="A">
    <module id="A">
<on event="next" to="D"/> </module>
<module id="D">
<on event="previous" to="A"/> <on event="finish" to="finish"/> </module>
<on event="cancel" to="cancel"/> <final id="finish" /> <final id="cancel" /> </application>

For configuring the module states and transitions between them is very convenient to use the state machines (Finite State Machine). After introducing inheritance and polymorphism into configuration it becomes a very powerful tool to describe business processes. For good visibility we used XML format of configurations files but it also can be some implementation of Domain Specific Language to be able to validate configuration on compile time.

As examples of such state machines in the Java world, can serve:

·  Spring Web Flow  – extension of Spring MVC and that’s why quite good to use with HTTP Request/Response model.

·  Lexaden Web Flow  – created especially for rapid development of flexible enterprise AJAX Vaadin applications.

The main difference is that Spring Web Flow  is mostly created for frameworks tightly coupled to HTTP Request/Response model and that’s why it might be cumbersome to use it with AJAX component frameworks such as Vaadin. The page will be refreshed all the time and benefits of AJAX will be ignored.

Lexaden Web Flow  instead gives you the whole power of described approach at the level of AJAX requests. Taking all the best from Vaadin component model it allows you creating flexible, scalable and very reliable enterprise applications.

P.S. the article Building An Advanced Navigation for Enterprise Applications describes in details the solution based on Lexaden Web Flow.

The Java Zone is brought to you in partnership with ZeroTurnaround. Discover how you can skip the build and redeploy process by using JRebel by ZeroTurnaround.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}