I haven’t been to the gym in a long time.
David Eaves, a person I have immense amounts of respect for, has been using a tag line related to this title/intro on his blog for quite a while, probably longer than I’ve known him. And I honestly never gave much thought to the idea that writing really is a muscle until recently. I’ve taken a break from being a designer (or a programmer) to work as a product manager for over a year now. Designing and coding require a set of skills I’m very familiar with, code is an interpretive language that people use to communicate with each other about the details of commands they issue a computer. While design is a more visual language of storytelling, heavily using imagery and some text to convey the journey of a user to the team intent on correctly interacting with that user. Both pursuits are about communication but each uses written language in a very different way. As a product manager I’m forced to lean on my skills as a writer and I don’t think I had much in the way of skills previously but whatever bedridden muscles have been dormant are reawakening as I realize how young and foolish I really was to ignore this essential form of communication.
I’m hoping there is more to come, perhaps starting with some tech posts about recent projects while I try to grapple with this idea of writing more than a tweet.
This is the first of a few posts that I’m planning regarding discussion about how we implement and work on the desktop and standalone parts of Firefox Hello. We’ve been doing some things in different ways, which we have found to be advantageous. We know other teams are interested in what we do, so its time to share!
First, a little bit of architecture: The panels and conversation window run in content processes (just like regular web pages). The conversation window shares code with the link-clicker pages that are on hello.firefox.com.
Hence those parts run very much in a web-style, and for various reasons, we decided to create them in a web-style manner. As a result, we’ve ended up with using React and Flux to aid our development.
I’ll detail more about the architecture in future posts.
The Flux Pattern
Flux is a recommended pattern for use alongside React, although I think you could use it with other frameworks as well. I’ll detail here about how we use Flux specifically for Hello. As Flux is a pattern, there’s no one set standard and the methods of implementation vary.
The main parts of a flux system are stores, components and actions. Some of this is a bit like an MVC system, but I find there’s better definition about what does what.
An action is effectively a result of an event, that changes the system. For example, in Loop, we use actions for user events, but we also use them for any data incoming from the server.
A store contains the business logic. It listens to actions, when it receives one, it does something based on the action and updates its state appropriately.
A component is a view. The view has a set of properties (passed in values) and/or state (the state is obtained from the store’s state). For a given set of properties and state, you always get the same layout. The components listen for updates to the state in the stores and update appropriately.
We also have a dispatcher. The dispatcher dispatches actions to interested stores. Only one action can be processed at any one time. If a new action comes in, then the dispatcher queues it.
Actions are always synchronous – if changes would happen due to external stimuli then these will be new actions. For example, this prevents actions from blocking other actions whilst waiting for a response from the server.
What advantages do we get?
For Hello, we find the flux pattern fits very nicely. Before, we used a traditional MVC model, however, we kept on getting in a mess with events being all over the place, and application logic being wrapped in amongst the views as well as the models.
Now, we have a much more defined structure:
- Components/views are a place for displaying, there’s some logic about what to display, but it isn’t business logic.
- The business logic exists in the stores, and is triggered by actions.
- You can follow an action through and find out which stores listen for it, and what they do.
- Actions themselves are well-defined with specified parameters.
React provides the component structure, it has defined ways of tracking state and properties, and the re-rendering on state change gives much automation. Since it encourages the separation of immutable properties, a whole class of inadvertent errors is eliminated.
There’s also many advantages with debugging – we have a flag that lets us watch all the actions going through the system, so its much easier to track what events are taking place and the data passed with them. This combined with the fact that actions have limited scope, helps with debugging the data flows.
Simple Unit Testing
For testing, we’re able to do unit testing in a much simpler fashion:
- Components/Views are tested by setting up their state and/or properties and ensuring the correct elements are displayed:
- Stores are tested by setting an initial state, sending an action, and checking the resultant state:
We therefore have many tests written at the unit test level. Many times we’ve found and prevented issues whilst writing these tests, and yet, because these are all content based, we can run the tests in a few seconds. I’ll go more into testing in a future post.
Here’s a few references to some of the areas in our code base that are good example of our flux implementation. Note that behind the scenes, everything is known as Loop – the codename for the project.
Conclusion and more coming…
We’ve found using the flux model is much more organised than we were with an MVC, possibly its just a better defined methodology, but it gave us the structure we badly missing. In future posts, I’ll discuss about our development facilities, more about the desktop architecture and whatever else comes up, so please do leave questions in the comments and I’ll try and answer them either direct or with more posts.