|
Home Services People Process More About Us |
More Background on Drawlets
Many years ago, Kent Beck and Ward Cunningham created a fantastic two-dimensional graphics framework for direct manipulation of drawings and more in Smalltalk. Over the years there have been many reinstantiations of this framework in various forms and many of its features have inspired key components of other graphical frameworks. You can find out more about the Smalltalk version of it at its own home page.
The Problem
Some have thought of Drawlets as a neat little drawing tool, others have thought of it as a basis for a powerful direct manipulation application framework. We choose to think of it as the latter. No matter what you call it, we've always been impressed with it as a simple, powerful example of a framework done well. Yet, there has always been something keeping it from being everything we'd like in a framework.
In fact, we have found that, as powerful as Smalltalk is, most frameworks we've seen suffer from a recurring problem. The class hierarchies do not always reveal the design behind them, and often even confuse those who inspect these hierarchies.
The Forces
Like others, we have felt that single inheritance is a powerful implementation concept, and multiple inheritance causes more problems than it solves (as an implementation concept). On the other hand, we've found that inheritance is a useful analysis & design concept in both single and multiple forms. It has been said that one of the great things about objects is that you have them at all stages of development and you can often find the same objects from analysis through implementation. This is somewhat true but has many exceptions. One of the areas we've seen it breakdown again and again in Smalltalk (and other single inheritance languages) is in the area of inheritance. This is, at least partly, due to the fact that there really is no explicit difference between implementation and design in Smalltalk.
Framework developers use abstract classes to define the interface of objects (design) and as the basis of their hierarchies of concrete classes of objects (implementation). They also, at times take advantage of the fully polymorphic nature of Smalltalk to allow objects in different hierarchies to be used interchangeably to perform similar roles. Unfortunately, there is no formal mechanism in Smalltalk to explicitly identify
Over the years, as we've applied Drawlets and other frameworks to new problems, we often found ourselves being dissatisfied with the fact that this truth about inheritance seemed to get in the way of keeping our frameworks "squeaky clean" when we used in a different context. We always seemed to be unhappy with some of our inheritance decisions, or the fact that some cool polymorphic trick was very hard to find unless we happened to read the right comment or the right page of the documentation (much of which did not always exist). Therefore, it was not uncommon to find multiple versions of the same framework evolving. This was good.
Unfortunately, as several versions of the framework evolved, bringing features of one version of the framework into another version became increasingly difficult as base classes varied significantly. This often lead to factions forming over versions of the frameworks. Each of the versions of the framework becoming more and more specialized, with the generic, "clean" framework becoming more and more obscure. So, developing new versions of the framework for yet another purpose became increasingly unlikely, and the attempts produced decreasingly less impressive results.
Java has come onto the scene recently (perhaps you've heard of it :-) with a significant set of language features that overlap Smalltalk's. Although there are many features of Smalltalk we miss in Java, we also find a few powerful features of Java that Smalltalk lacks. The most powerful one is the concept of interfaces, which enable developers to separate design inheritance from implementation inheritance.
The Solution?
Therefore... framework developers should use explicit interfaces in Java to delineate the major roles in the design of the framework. In essence, the design of the framework should be captured completely in interfaces and various kits of abstract and concrete classes should be built on top of it. Whenever possible, the classes in the kits should collaborate with other objects through interfaces, not other classes. References to classes should be limited to constructing new objects whenever possible (since only concrete classes actually do anything).
This yields the following results:
Drawlets as an Example of Unusually Adaptable Software
We first attempted to explore these ideas by reimplementing the Drawlets framework in Java. We believe even our first attempt demonstrated the significance of separating design inheritance (interfaces) from implementation inheritance (classes). Since then we've applied further principles for framework development which are captured in Patterns for Building an Unusually Adaptable Java Framework.
To test our claims, consider downloading it. You may also want to check out the demo applets which are built with it (but don't think that what you see in the applets is all you get).
Try to use it in various contexts. Here are just a few ideas to get you started:
Let us know if our assertions above hold up, or if you have any other observations you'd like to share. (Please send us feedback)
| Copyright © 2002-03 by RoleModel Software, Inc. All rights reserved. |