Mimosas 1.0, Smalltalk-style MVC

Mimosas implements MVC's original Smalltalk-80 architectural system. It is an honest attempt to disconnect from all the fancy modern development paradigms and reconnect with the basics of MVC.

By on
An upclose shot of a bright pink mimosa flower with yellow blossoms
Mimosa Blossom Macro, by .

Over the past few years I’ve begun to explore application architecture in earnest. My latest attempt, Mimosas, has worked out well in production so I gave it the big 1.0. Here’s its first introduction to the world.

Module, Facade, Mediator architecture

My first real attempt at a cohesive architecture was Aura, co-created with Addy Osmani and later brought to life by many other very talented engineers. From the about page:

Aura is an event-driven extensible architecture for wrapping your code into reusable components and extensions that can easily communicate with each other.

Aura works great with existing frameworks like Backbone.js or Ember, but is framework-agnostic, adapting many best-practice patterns for developing maintainable applications.

Request-driven architecture

Later that year I started thinking about the solution to a host of architectural issues I was facing at work. After months of consideration, I attempted a re-interpretation of an old Java stand-by, Request Driven JavaScript Applications with Core J2EE Patterns.

I got turned on to the Core J2EE patterns while reading PHP Objects, Patterns, and Practice by Matt Zandstra. In his book, Matt demonstrates a super common approach to PHP apps using the J2EE patterns as a guide. I’ve come to call this approach request-driven, and it is used by many if not all of the most popular PHP frameworks.

The request-driven approach mostly means that the URL drives the behavior of the application. Backbone and a few others do this with Routes, but it is fairly de-emphasized in comparison to server-side frameworks.

I’m proud to say that my implementation of the request-driven architecture has been in production for several years now. It’s had a ton of testing and real world use by some huge brands, under some pretty decent traffic. It’s really turned out to be a hit in my mind.

MVC as it was intended1

For some time I have been dissatisfied with the state of MVC frameworks. Most aren’t truly MVC and many are very difficult to use. Maybe this is because documentation about the original MVC implementation is fading away. Or maybe it’s due to a collective misunderstanding about MVC in general.

Authoritative documentation on the Smalltalk approach to MVC is hard to find. I read white papers, blog posts, books, and source code in search of The One True MVC. I consider Applications Programming in Smalltalk-80™: How to use Model-View-Controller (MVC) by Steve Burbeck, Ph.D and A Description of the Model-View-Controller User Interface Paradigm in the Smalltalk-80 System (PDF), by Glenn E. Krasner and Stephen T. Pope, to be canon. Design Patterns: Elements of Reusable Object-Oriented Software, does a great job of explaining how each part of the MVC triad should be implemented with the GoF design patterns.

I wanted to try to create a JavaScript based MVC framework that was true to the original implementation. To do this, I basically had to reverse-engineer MVC from the canonical sources and bits of Smalltalk 80 lying around the web. I’m really happy with the result. I called it Mimosas, which also happens to be (what I think) is a clever little recursive acronym:

Mimosas implements MVC’s original Smalltalk-80 architectural system. It is an honest attempt to disconnect from all the fancy modern development paradigms and reconnect with the basics of MVC. The aim is not to be a clone of Smalltalk MVC, but to capture its spirit, build upon its foundations, and possibly make something useful in the process.

How it works

As in Smalltalk, Mimosas divides an application into three parts, the model, view, and controller.

In Smalltalk-80 views were always hierarchies, with one single “top view”, and many child views. A single view could represent both single items, such as a checkbox, or more complex components, such as a list of selectable items.

In Mimosas, the top view and other views which can have children implement the ViewComposite class, which is the Composite in the Composite pattern. Views that do not have children implement the ViewLeaf class, which is the Leaf in the Composite pattern. Both classes inherit from the ViewComponent (Component), which in turn inherits from the ViewObserver (Observer).

Views and controllers are tightly coupled. They both maintain a reference to the other. Mimosas minimizes this coupling by forcing views to communicate with their respective controllers through the ControllerContext class, which is the Context part of the Strategy pattern and can be viewed as a sort of Facade in this scenario. This communication happens transparently.

Lastly, models can be strings, a single object, or a collection of objects. Smalltalk didn’t really care, as long as they inherited from a base object. In Mimosas that object is the ModelSubject.

Installation

Mimosas doesn’t have any dependencies. The only file that is required for use in your project is mimosas.js. There are three options for obtaining this file:

Once you have Mimosas somewhere in your project, check out the Getting Started section.

Getting Started

You can use Mimosas in the browser with AMD and globals, or on the server using Node. This is accomplished with the returnExports UMD pattern. The controller/view event handling needs to be refactored to work without the DOM on the server side.

// Node
var Mimosas = require('libs/mimosas');

// Browser AMD
define(['libs/mimosas'], function (Mimosas) {});

// Browser Globals
window.Mimosas;

Next, create your Models, Views, and Controllers by extending Mimosas core classes. If you’re using plain JavaScript you’ll need to manage inheritance using the Mimosas.Class.extends method. Whenever there’s talk about “extending a class” use this pattern with your constructor functions:

var MyClass = (function(classToExtend) {
  Mimosas.Class.extends(MyClass, classToExtend);
  function MyClass() {}
  // ..prototypes
})(ClassToExtend);

Here’s a basic example:

var Model = (function(classToExtend) {
  Mimosas.Class.extends(Model, classToExtend);
  function Model() {}
  // ..methods
})(Mimosas.ModelSubject);

var View = (function(classToExtend) {
  Mimosas.Class.extends(NewSongView, classToExtend);
  function View() {}
  // ..prototypes
})(Mimosas.ViewLeaf);

var Controller = (function(classToExtend) {
  Mimosas.Class.extends(NewSongController, classToExtend);
  function Controller() {}
  // ..prototypes
})(Mimosas.ControllerStrategy);

If you’re using CoffeeScript it’s a little easier. For example:

class Model extends Mimosas.ModelSubject
  # ..methods

class View extends Mimosas.ViewLeaf
  # ..methods

class Controller extends Mimosas.ControllerStrategy
  # ..methods

Within the project I have included two examples that will help you to structure your application in a sensible way. One is a command-line application and the other is for use in the browser.

In a very meta way, the source code itself is an example of how to combine patterns to form working applications. When I began learning about design patterns I had a very difficult time understanding how to do this. Maybe it will help someone else.

Parting thoughts

I never started out for this to become yet another MVC framework. Honestly, it was a personal project that grew into something bigger (at least in my head). But what I’ve learned is MVC as existed 20-plus years ago was simple, understandable, and extendable in ways that are rarely seen these days. No wonder it was so transformative!


  1. It has been argued that MVC is not an architecture. Based on my understanding of the Smalltalk implementation, I believe the intention was that it would serve as architectural framework. I agree and now have proof that MVC can absolutely work as an architecture. [return]