The Awesome Power of MVC Web Applications
David Lynch
Full-Stack Software Engineer - JavaScript React Redux Meteor Node.js MongoDB - Architect - Project Lead
In the mid-1990s, I became obsessed with the Observer pattern. Geeks familiar with book Design Patterns will immediately know what I'm talking about, but for the less technical, understand that the Observer pattern describes a standard way to publish and subscribe for notifications of events.
The Observer pattern is so powerful that I feel compelled to explain it to you. Imagine that you have written a function in your chosen programming language (JavaScript if you share my religion), and you want your function to be invoked when:
- A user does something to the user interface, such as entering a value into a field or pressing a button.
- A particular record or records in the database are updated.
In modern applications, dealing properly with UI events and database state-changes is key to solid application design. A well-written event-emitting subsystem will expose an API function to allow you to register a listener, which is a function that you supply. You supply your listener to the event-emitting subsystem, and the event-emitting subsystem will add your listener to a list of of listeners. The event-emitting subsystem will notify all listeners in that list whenever the event in question occurs.
If you look at the program logic within a typical event-emitting subsystem, at key control points, you'll see something like this:
Something important has occurred, let's iterate over the list of the event listeners that have subscribed, and invoke those listeners one by one, supplying each function with helpful information about the event so they can deal with it as they wish.
If you are following, you'll see that there is no magic, but from the subscriber's point of view, it looks like magic. Given the Observer pattern, it is practical for you to write a program that is 100% event driven. Your program literally sits there in memory doing nothing, waiting for your event listeners to be invoked by event-emitting subsystems.
I've implemented many systems that comply with a standard that I call Absolute MVC, an extreme adherence to the MVC design pattern where the view (UI) can be seen conceptually as a mirror that faithfully reflects the state of the model (in bleeding-edge React applications, this is tantamount to saying that the view reflects the state of the database). Absolute MVC applications tolerate arbitrary state changes, faithfully mirroring them to the view in a 100% deterministic manner; that is, given any state of the model, an application can infer the state of the view without referring to anything else. Such an application can be seen as a radical simplification, because it consists only of:
- Declarative rules for deterministically rendering the view given the state of the model.
- Transactional functions that change the state of the model in response to events.
Let that sink in: a typical SaaS application doesn't do anything except update the database, and then reflect the state of the database to user views.
Since the UI is capable of reflecting arbitrary state changes, developers are free to code new transactions that update the database in novel ways without adversely impacting the UI. This freedom enhances developer productivity and happiness, ultimately reducing development and maintenance costs.