danielv at techunix.technion.ac.il
Sun May 21 08:30:29 UTC 2006
> On 5/20/06, Daniel Vainsencher <danielv at techunix.technion.ac.il> wrote:
[cyclic dependencies make decomposition harder]
Ralph Johnson wrote:
> Classes are not modules. A module will include methods added to other
> classes. So, it is possible for class A to refer to B and class B to
> refer to A, but A and B are in different modules with no cycles.
> Suppose class A is in module X, and it depends on module Y, which
> contains class B. Then the method in B that refers to A is actually
> part of module X, even though most of B is in Y.
> I don't know the example you are talking about, and it might very well
> be an example of something that needs to be fixed. But the fact that
> Object has an "inspect" method doesn't mean that the entire GUI is in
> the same module as Object.
> This *does* make a system difficult to decompose because you can't
> assume that you can just assign classes to modules and be done.
That is definitely part of the problem I am talking about. And this
situation is very common - in the case of Squeak circa 3.7, this sort of
analysis showed that the largest strongly connected component in Squeak
included roughly half the classes in the system.
So indeed, for the easiest, "high" modules (application modules that
happen to have some reference from a framework), moving a few methods
might be enough to make them a properly bounded module, after these
methods are found. So a significant part of the modularization work is
making this kind of distinction - this method that appears in this
class, should be an extension from that module. And hopefully MC2 will
make the technical work to move the method from one to the other easier
than it is now.
But unidentified extension methods are not the whole story, of course.
In the common case, the functionality is actually being used by other
modules in some way, and real refactoring is needed in order to separate
them. For (a simple) example, Celeste (a mail client) used to have a
hard coded reference from World menu. As of ~3.4 we have a dynamic world
menu (a registry), removing that particular reference, and allowing the
extraction of several other applications from the big ball of mud.
In fact, Celeste had about 3-4 "extension method" problems, the world
menu reference I mentioned above, whose solution was general and of
benefit to other modules, and it also had a specific customized usage in
EToys, which required a little more tailored refactoring, which was
later generalized into an application registry.
I think Celeste is a typical case of what it takes to make a relatively
simple, standalone application unloadable. Several (most?) such
applications have already been removed (old IRC client), and some more
complex modules have also been so treated - IIRC the PlusTools are a
loadable version of the classical browsers, so maybe we can unload the
All of the problems I mentioned show up as cyclic dependencies. For the
simple case of a top-level application module, it by definition should
have no incoming references, which is even easier to find. AFAIK, we
currently have no deployed tools that highlight any of these cases
automatically, or make it any easier to solve the simple "extension
The up side is that part of the reason that cyclic dependencies matter
is that they give so much trouble in the use of MC1. If MC2 or Naiad can
handle them better, then solving the cyclic dependencies can be done
more incrementally, which is probably a good thing.
More information about the Squeak-dev