33. What the Flux?
Unidirectional Data Flow
Conceptual Integrity
“a system must have a powerful metaphor that is uniformly applied throughout a system“ – Alan
Kay
Move Fast With Stable Infrastructure
Reliability
37. Actions
Can be anything that changes the state of your data
User generated events
Server events
Real time updates
Error Handling
38. Dispatcher
Key to unidirectional data flow
Central Hub/Callback Registry
Manages dependencies between Stores
waitFor(ids)
Keeps State in Stores, closer to the logic that updates
that State
47. How do we convince people that in programming simplicity and clarity —in short:
what mathematicians call "elegance"— are not a dispensable luxury, but a crucial
matter that decides between success and failure?
Edsger Dijkstra
Editor's Notes
The point of this talk is ultimately to explain the Flux architectural pattern
But, in my research, I dig quite a bit of digging and felt it necessary to provide some history, or software archaeology if you will, on MVC.
It should provide a solid base before diving into the Flux pattern.
I’m a SE at f[23]
Graduate of FSU and UNF with degrees in Music and Computing
I love fishing, guitar, and potent potables.
MVC was initially created by TREEG-VUH RHEINS-COW Trygve Reenskaug in 1970s, at Xerox PARC, while he was working with Alan Kay on the Dynabook
The Dynabook (or KiddiComp) was first envision by Kay in 1968 as an educational computer for kids. Tablet/slate
Originally Model-View-Controller-Editor
Editor was a temporary component that the View created to interface with keyboard and input devices
Originally Smalltalk-76, but first real appearance was Smalltalk-80
The first significant paper published on MVC was "A Cookbook for Using the Model-View-Controller User Interface Paradigm in Smalltalk -80", by Glenn Krasner and Stephen Pope, published in the August/September 1988 issue of the JournalOfObjectOrientedProgramming (JOOP).
MVC was initially created by Trygve Reenskaug TREEG-VUH RHEINS-COW in 1970s, obviously at Xerox PARC, while he was working with Alan Kay on the Dynabook
The Dynabook (or KiddiComp) was first envisioned by Kay in 1968 as an educational computer for kids. Tablet/slate
Originally Model-View-Controller-Editor
Editor was a temporary component that the View created to interface with keyboard and input devices
A few previous versions, but first real appearance was Smalltalk-80
The first significant paper published on MVC was "A Cookbook for Using the Model-View-Controller User Interface Paradigm in Smalltalk -80", by Glenn Krasner and Stephen Pope, published in the August/September 1988 issue of the JournalOfObjectOrientedProgramming (JOOP).
Current interpretations and implementations of MVC differ from the original intent
Back in the 70’s, GUIs weren’t as common, and a concept known as Separated Presentation began to be used to differentiate between domain objects and
Presentation objects
Smalltalk-80’s implementation of MVC took it a step further and had an objective of separating out the application logic from the UI
The idea was pushing for reuse of the domain models to further reuse in other UIs in the application.
In Smalltalk-80’s implementation:
A model represented domain specific data and was ignorant of the user-interface. When a model changed, it would inform its observers.
A View represented the current state of a Model. The Observer pattern was used for letting the View know whenever the Model was updated or modified.
Presentation was taken care of by the View, but there wasn’t just a single View and Controller, a View-Controller pair was required for each section or element being displayed on the screen.
The Controller’s role in this pair was handling user interaction (key presses and actions), making decisions for the View.
So here are two different versions of Smalltalk
In both, and in practically all MVC implementations, the model does not depend on the view or the controller
Observer pattern was used to update views when models changed
For SECOND slide
Smalltalk-80 MVC did not make a view/controller separation
Notice that the user interactions start in the View or the Controller-View pair
So, this is an evolution away from the MVCE pattern and the two previous Smalltalk implementations, where the controller is separated as well as accepting and responding to user interactions
Messages can be passed from the Controller or the View into the Model to update it’s application state
Changes are then signaled back to either the Controller or the View
The View can update itself based on some changes in the model, or by way of a Controller message
It's a lot different from the original Smalltalk MVC pattern since Rails operates in a very different environment than a typical Smalltalk application
Again, the model does not depend on the view or the controller
There isn't a direct dependency between the view and the model. The controller collects all the needed data from the model and passes it to the view
Given that Rails operates in a client-server environment the view does not update automatically when the model changes
Most of today's MVC web-frameworks use a pattern very similar to the one Rails uses
Cocoa's MVC puts a lot importance on the controller and this makes it a lot different than the original Smalltalk MVC.
A Cocoa controller acts as a mediator between the view and the model [this is commonly known from the Mediator pattern]:
The reason to use the mediator pattern is probably because the data flow is cleaner than the traditional MVC found in Smalltalk
Familiar Concepts and Patterns:
Easy to learn (most of the time)
Many developers are familiar with some implementation of MVC on the server. ASP.NET MVC, RoR, Spring
Allows for fast prototyping, garnering client feedback, A/B Testing, etc.
Uniformity for developers across the team
And most of the time, when things break, you’ll know where to look
Typically obfuscates some of the less attractive and unreliable parts of JavaScript. This is good and bad.
Rapid development cycles
Testable
Better debugging (sometimes)
Modularity/Reusability and Maintainability
Helpers for security, templating, routing, data-binding etc.
Shorter learning curve (sometimes)
Real time/native feel
Asynchrony
Flashy Controls and Components
So, who do we turn to?
Complex Models:
KVO and 2-way DB can trigger cascading updates, which in turn triggers re-rendering, repainting, and reflowing of related DOM elements.
Deeper object graphs can quickly turn a few observables or bindings into thousands
It’s difficult to debug or trace these types of data-bindings
Explicitly and declaratively registering for changes makes things much simpler than binding a property of your model to your view, then trying to wrap some logic around it.
Data-Binding Solutions:
Data binding solutions are constraining. It should be an opt in.
Non-trivial abstractions (leaky)
They should at least be minimally leaky and provide the developer an escape hatch
Remember that in practically all implementations we’ve seen, there’s never a direct dependency between the Model and the View
Framework Constraints:
If the Framework doesn’t support it, you’re on your own
Whenever you encounter things that the creators of the framework didn’t anticipate, sad face.
Choosing one framework may cause problems in using third party libraries or other solutions. Sad face.
Initially, I referenced this in my React talk, but there’s a different side to it from an MVC/FLUX Point of View
Templating Engines are crippled by default.
You are at the mercy of the templating engine and whatever its API offers you
If we look back at traditional MVC, it’s the Views job to handle Presentation Logic.
Pushing this logic into a templating engine isn’t separating a concern, it’s separating a technology, but for what? Looser coupling?
Higher cohesion is favorable here. If you accept that, you gain the full power of JavaScript to determine your Presentation Logic versus the constrained
Set of functionality provided by your templating engine.
Unidirectional Data Flow
All of your data flows in one direction, similar to function-reactive programming
There are no two-way data bindings
Conceptual Integrity
Simplicity and digestible concepts are key to Flux
Simplicity allows for better diagnosing of bugs, quicker ramp up time for new developers, and rapid refactoring of large portions of functionality
Move Fast
Zuckerberg quote
Predictability, reliability
Again, being predictable not only makes it easier to debug, but it makes the entire application and application lifecycle easier to think about, allowing the developer to focus on the domain and issues at hand.
Reliability
Lack of leaky abstractions, data binding solutions, and implicit code leads to more reliable code.
Declarative, explicit, pure functions lead to more readable , comprehendible, and reliable code.
Maintain UI state
Controller-Views sit at the top of a hierarchy and listen for changes that child components may be interested in.
Typically, they’ll pass the entire state of the specific domain along to its children, keeping them all in sync.
Maintain app state allows different parts of the app to remain highly decoupled.
When dependencies do occur, they’re managed hierarchically and synchronously through the dispatcher
Stores manage app state for a specific domain within the application
Typically manage many objects
Actions are really discrete, semantic, helper functions that ease passing data to the dispatcher
Callback/Registry
Stores register themselves and provide a callback for the Dispatcher to send payloads to
This is the single entry point into each store for all mutations to take place
All of your getters can be publicly exposed in your stores so that your React Components can interrogate current state.
Dependencies
waitFor accepts Store tokens so that you can explicitly tell the dispatcher which stores you want to update first
You can create cycles