Partial ordering of qooxdoo classes
Filed under: Development, Tool Chain
By Thomas Herchenröder @ March 17, 2008 5:18 pm
This article is for the theoretically inclined among us :-).
When putting together a JavaScript application order matters. Since the browser
evaluates JavaScript code in the order it arrives, every code that is referenced
by other code has to come beforehand, in order for that reference to succeed.
This for example affects calls to other functions within the body of a certain
function, since these references are resolved at load time by the interpreter.
The same holds true for the prototype reference used for a "derived" class
(constructor) object. The "ancestor" function has to be loaded before you can
use it as the prototype for another function.
In qooxdoo, classes are declared as maps which are passed to a
class-constructing method, qx.Class.define(). This method creates the basic constructor object, sets the prototype and other prototype properties, and so forth. It is only when qx.Class.define is actually executed that all referenced objects in the class definition have to be in place, the most prominent being the "extend" member of the class which names its parent class.
qooxdoo's generator goes to some length to assure that classes are constructed in the right order. This is reflected in the script/<application>.js file which contains a list to the appropriate class files (in the "source" version), or the actual class code (in the "build" version). Obviously, classes that serve as base classes for others have to come earlier. But this is not all there is to it. Classes not only inherit from other classes, they also use them, through creating instances of them in their own code or calling out to static functions. Whenever code that does that is evaluated those other classes have to be in place.
You probably already know where this is going to, there is a risk of circular dependencies. A simple example might illustrate that. Most classes in qooxdoo derive from qx.core.Object, e.g. the Logger class. But qx.core.Object itself might want to start logging early when it is created, that is "use" a Logger instance. Another typical example for complications of this kind is the 'tr' function that needs a qx.locale.LocalizedString, which might not be present at the time you call 'tr'. A point in the class declaration where this might crop up is the 'defer' section, which contains code that is actually run after the class has been constructed, but might include references to classes that are not readily present in the interpreter.
On a general level what we are looking for is a partial order on the set of qooxdoo classes, the relations in question being "require" (the other class is a parent class) and "use" (the other class is used in the code). The question is: Is there a partial order for the qooxdoo classes under the combined relation "require/use" where a class A "comes before" a class B exactly when A is required by B and/or A is used by B. Only if there is such an order can qooxdoo classes be sequenced consistently.

Comment by Meneer R
Well, the ability to create such an order is good measure of quality.
The more complete the ordering, the better the framework is organized.
If the order is almost horizontal, that means a complete restructure might not be such a bad idea. Personally, i believe that _mixins_ are the way forward. Inheritance is overrated and often abused, and at the very least a little problematic.
A re-structure where the majority of inheritance relationships are replaced with mixins and composition relationships is a great improvement to any framework. The amount of over-designing that takes place to make everything fit in the inheritance model does not make it more modular, nor more maintainable.
Something about a how everything is a nail if you ask a hammer.
In qooxdoo too, i find that inheritance is often over-used, whereas (abstract) mixins would suffice. Examples:
- sizeable (adds width,height properties)
- displayable (adds support dom-node creation, caching and destroying methods)
- dispatchable (adds event-handling-support)
- value (add the getValue and setValue commands and validation support)
- appearance (adds appearance/theme support)
- label (adds label functions and translation support)
- navigational (adds statefull navigational element, with automatic browser-history support)
etc.
Most of these should be abstract: that is they require that you implement some or methods. The perfect implementation would allow the creator of the class to specify constructor arguments to each of these.
Mixins’ should be able to have both internal and external dependencies on other mixin’s themselves. The external dependencies should be constructed by the user of the mixin, whereas the internal are constructed by the mixin themselves and are not directly available to the user.
But like I said before, i think this would be great for all frameworks. Nothing qooxdoo specific. I could say the same for most of the java and .net frameworks.
March 19, 2008 8:11 pm
Comment by Thomas Herchenröder
@Meneer R: Thanks for your interesting comment, you give us something to think about …
March 19, 2008 9:54 pm