DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

MVC Is Dead, What Comes Next?

In the beginning of a series, we take a look at how UI frameworks like React.js have introduced an alternative to using MVC as the primary method of designing web applications and UIs. Read on to find out more.

Michael Heinrichs user avatar by
Michael Heinrichs
·
Oct. 16, 16 · Opinion
Like (76)
Save
Tweet
Share
79.53K Views

Join the DZone community and get the full member experience.

Join For Free

React.js, Elm, Cycle.js, and other UI frameworks introduced a new way of building user interfaces. By applying principles from functional reactive programming to UI development, they even changed how we think about user interfaces. In no time, these approaches have simply smashed the seemingly inevitable dominance of MVC and its siblings (MVP, MVVM etc.). This article, which is the first in a series, will give a brief introduction into this new way of building UIs and list some of the advantages it has over traditional approaches. These factors are so strong, that in my opinion there is a good chance that we are right now witnessing the end of the MVC-era.

Graph showing the cyclic dependency between DOM Driver, ActionCreator, Updater, and View()

Concept of functional reactive UI development

On the face of it, frameworks like React.js with the Redux-architecture, Elm, and Cycle.js seem quite different. Redux applications initially appear to be similar to regular JavaScript application, perhaps with a strong focus on functional programming. Elm-applications come with their own language, while Cycle.js applications consist of reactive streams only which are knotted together in astonishing ways.

But under the hood, all of these frameworks have something in common: the essence of functional reactive UI development.

The picture above shows a rough overview of the concepts, which are shared between pretty much all modern UI frameworks that foster reactive programming. The first thing to note is that everything – all changes, events, and updates – flow in a single direction to form a cycle. This article will give just a brief explanation of the cycle, while later articles will go into more details.

Functional Reactive UI-development

The cycle consists of four data-structures (State, Virtual DOM, Event, and Action) and four components (View()-Function, DOM-Driver, ActionCreator, and Updater). The DOM-Driver is provided by the framework, while the other components have to be implemented by the application developer.

Let’s assume our application, a todo-list, is already running for a while and the user presses a button to create a new entry in the todo-list. This will result in a button-clicked event in the DOM, which is captured by the DOM-Driver and forwarded to one of our ActionCreators.

The ActionCreator takes the DOM-event and maps it to an action. Actions are an implementation of the Command Pattern, i.e. they describe what should be done, but do not modify anything themselves. In our example, we create an AddToDoItemAction and pass it to the Updater.

The Updater contains the application logic. It keeps a reference to the current state of the application. Every time it receives an action from one of the ActionCreators, it generates the new state. In our example, if the current state contains three todo-items and we receive the AddToDoItemAction, the Updater will create a new state that contains the existing todo-items plus a new one.

The state is passed to the View()-Function, which creates the so-called Virtual DOM. As the name suggests, the Virtual DOM is not the real DOM, but it is a data-structure that describes how the DOM should look like. The code snippet above shows an example of a Virtual DOM for a simple <div>. A later article will explain the Virtual DOM and its advantages in detail.

The Virtual DOM is passed to the DOM-Driver which will update the DOM and wait for the next user input. With this, the cycle ends.

Advantages

Functional reactive UI Development has three major advantages over traditional approaches, all of them are huge: straightforward testing, a comprehensive flow of events, and time travels (yes, seriously).

Straightforward testing

The View()-Function and the ActionCreators are simple mappings, while the Updater performs a fold (also often called a reduce) on the Actions it receives.

All components are pure functions and pure functions are extremely easy to test.

The outcome of a pure function depends only on the input parameters and they do not have any side effects. To test a pure function, it is sufficient to create the input parameter, run the “function under test” and compare the outcome. No mockups, no dependency injection, no complex setup, and no other techniques are necessary that take the fun out of testing.

Comprehensive Flow of Events

Reactive programming is a lot of fun – except when it is not. The control flow of graphical user interfaces is inherently event-based. An application has to react to button-clicks, keyboard input, and other events from users or servers. Applying reactive techniques, be it the Observer Pattern, data-bindings, or reactive streams, comes naturally.

Unfortunately, these techniques come with a price. If a component A calls a component B, it is simple to see the connection in your IDE or debugger. But if both components are connected via events, the relationship is not as obvious. The larger the application becomes, the harder it gets to understand its internals.

The architecture of a functional reactive application avoids these problems by defining a simple flow of events that all components must follow.

No matter how large your application grows, the flow of events will never change.

Time Travel

Functional reactive applications allow you to travel back and forth in time – at least in the context of your application. If we store the initial state and all actions, we can use a technique called “Event Sourcing”. By replaying the actions, we can recalculate every state the application was in. If we replay only the last n-1, n-2, n-3… actions, we can actually step back in time. And by modifying the recorded stream of actions while applying them, we can even change the past. As you can imagine this can be very handy during development and bugfixing.

The first time-traveling debuggers have been built, but I think we have only started to understand the possibilities, and more amazing tools will be released in the future.

Summary

So far we have only touched the surface of functional reactive UI development, but by now it should be clear that this approach has some tremendous advantages. Future articles will go deeper into the technical details, but also show the disadvantages (or let’s call them “yet-to-solve-challenges”), and show an example how the lessons learned can be applied to JavaFX applications.

application

Published at DZone with permission of Michael Heinrichs, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Unlock the Power of Terragrunt’s Hierarchy
  • Important Data Structures and Algorithms for Data Engineers
  • 5 Common Firewall Misconfigurations and How to Address Them
  • How Elasticsearch Works

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: