Between early 2006 and early this year, my team at IBM Rational and I built a framework for component-based Ajax development for use in the Rational Jazz platform. The framework’s capabilities aren’t the focus of this entry, so I’ll just list some of them briefly:
- A nice component model based on OSGi bundles and the Dojo module system
org.eclipse.core.runtimeextension registry Java APIs, allowing for open-ended extensibility using the Eclipse extensibility model
- A simple framework for demarcating UI states that made the back button, history, and page titles work seamlessly within the Ajax page, even when a user gesture resulted in crossing a component boundary (e.g. loading and displaying a new virtual “page” from a different component) 
- Dynamic, transparent loading of missing code in response to a user gesture that required it
We did a fairly good job of keeping our Ajax framework decoupled from the rest of the Jazz Platform both for the purpose of design cohesiveness but also to allow for possible future use by teams who weren’t building full-blown application lifecycle management applications like Jazz SCM or Iteration Planning.
Over time, other IBM teams heard about some of our capabilities and saw the positive results in our Rational Team Concert web UIs  and contacted us to explore whether they could make use of our code in their products. Each conversation went like this:
- We gave a demo and talk about the capabilities and architecture of the framework
- The other team said “that’s really nice, that’s really useful, that would be great to have”
- The other team said “we’re not sure we want to live within your framework, we’ll get back to you”
- The other team didn’t get back to us
Initially this didn’t really bother me – after all my job was to deliver the foundation for our Jazz web user interfaces, not to create a general purpose Ajax framework for IBM, but as I’ve thought about it more over time and seen this anti-pattern from other teams and other frameworks, I’ve decided that we should make a conscious effort to make our useful functionality available as simple building blocks (in the form of libraries) and then provide frameworks that layer on top of these building blocks.
Let me take a step back and explain what I mean.
A library is a set of reusable functionality where your application uses parts of the library as necessary. For instance, most programming languages have a library for creating and manipulating dates. Frameworks also provide functionality to the application programmer, but instead of the application programmer making simple function calls, the framework runs the show and calls into the application at well defined hook points. For example, GUI frameworks provide ways to wire up code to run in response to users clicking on buttons.
Both the library and the framework provide useful functionality intended to make the application developer more productive. Though it’s dangerous to make a general statement, it feels to me that the big difference between the two is that frameworks generally provide more power, but require you to make a bigger commitment to the framework’s way of working, while libraries provide generally less power, but make few (if any) demands about how you structure your application.
What’s unfortunate is when you’ve got some useful bit of functionality that could be made available as a simple library but it’s only available in the context of a framework. This is where we were with our Ajax framework. This stuff is too abstract, so here’s an analogy: Imagine that you heard about a new refrigerator which provided every feature and characteristic you ever dreamed about having in a refrigerator. The catch however was that you couldn’t just buy the refrigerator – you had to move into a house on the other side of town that included the new refrigerator. After about 10 seconds of thought you realize that even though it’s the fridge of your dreams, you’re sure as hell not going to move into a new house across town in order to get it. This situation (switching back to software from refrigerators) is shown in the diagram below.
My recent realization (which seems obvious in hindsight) is that the useful functionality provided by frameworks and libraries need not be mutually exclusive. For instance, in our Ajax framework’s dynamic build system, rather than requiring applications to run within our framework to enjoy this capability, we could have created a simple callable library to perform dynamic optimization on a set of files, and then created a framework that simply used this same library. This approach is shown in the diagram below:
Over the past month or so we’ve been refactoring our Ajax framework to extract the useful building blocks into simple callable libraries and making the framework proper smaller by delegating to these libraries. We’ve done this in the hopes that our code will be useful to other IBM teams but as a result of the exercise, we’ve gained a deeper knowledge of our software and the software’s quality has improved as we’ve decoupled the framework aspects from the building blocks aspects.
Going forward, it’s my intention that our team will generally start with building blocks first and then consider if we should provide some higher-level framework that uses these building blocks. I only wish we had taken this approach from the beginning but you know, live and learn.
- This UI state management framework evolved into dojo.hash
- You can see our Jazz web UIs built on top of this framework in the development section of Jazz.net if you register.
Changed “other than writing good code” to “other than writing good application code”