How bad is Netty's class structure? Let's compare its class-level structural disorder to our other reviewed systems.
Program | Class structural disorder |
Netty | 79% |
Junit | 78% |
Lucene | 70% |
Spring | 60% |
Ant | 56% |
FitNesse | 55% |
Struts | 42% |
Table 1: Class-level structural disorder of all programs reviewed in this series.
Why is Netty's class structure so bad?
Well, it's not entirely clear.
As we saw from package-level, Netty's programmers arranged its packages so that a layer of clients tends to use a core set of service packages, the internal/concurrent/channel/buffer/util cluster. This exemplifies good package design. If, however, the classes of these packages are poorly structured and poorly encapsulated, then this might explain the overall class-level disorder.
Let us then analyze these five packages.
Ideally packages should play one of two roles: they should either be client - which has no dependencies on it, and which depends on other packages - or server - which depends on no others. Packages which are equal part client and server can lead to long class transitive dependencies and hence lead to disorder.
So if we take all the classes in concurrent, say, and count their combined impact set, that is all classes that they depend on, we find that its classes depend on 51 classes in other packages. Conversely, if we count the classes in concurrent's impacted set, we find that 437 classes depend on the classes of concurrent. With far more depending on than depended upon, the classes of concurrent form quite a satisfactory server package.
Table 2 shows a similar analysis for all core packages.
Package | # Classes | Impact set | Impacted set | Disorder-on density | Amplification density |
channel | 131 | 74 | 347 | 5.0 | 103 |
internal | 39 | 95 | 567 | 5.7 | 330 |
buffer | 92 | 43 | 219 | 4.3 | 61 |
concurrent | 67 | 51 | 437 | 1.7 | 69 |
util | 48 | 27 | 252 | 2.3 | 54 |
Table 2: An analysis of the classes in the core five packages.
Table 2 shows that all the packages play server roles, with perhaps the exception of internal. Though server-oriented, the classes of this package depends on over twice as many classes (95) as the package itself contains (39). This is not ideal as it offers opportunity for long transitive class dependencies passing right through the package.
We can also look at how each package contributes to the overall class-level structural disorder. The, "Disorder-on density," shows the number of disordered (non-transitive) dependencies on the classes of each package ("Density," means that total figure is divided by the number of classes in each package). Clearly channel and internal are ahead in this unfortunate metric, causing more disorder than the rest of the packages.
We can, furthermore, examine the amplification of the classes of each package. Amplification is just an unusual spike in the number of transitive dependencies caused by a class's having many dependencies-on and dependencies-from, often involving circular dependencies. Table 2 shows the amplification density - amplification per contained class - and again both channel and internal do themselves no favours (internal's amplification especially raises eyebrows).
All this suggests that perhaps both channel and internal would be good places to start investigating Netty's disappointing class structure, though perhaps for different reasons.
It may be that channel is simply too large. Figure shows a spoiklin diagram of the classes in the channel, where each circle now represents a class.
Figure 1: The classes of package io.netty.channel
These dependencies are clearly unclear; perhaps splitting it in two might help?
Figure 2 shows the classes of package internal.
Figure 2: The classes of package io.netty.util.internal
Figure 2 shows that the classes of internal are quite well-structured, offering easy tracing of inter-class dependencies. This view in isolation, however, is deceptive: table 2 hints that internal's problems lie not its intra-package class dependencies but its dependencies on the classes of other packages.
Of course, no definitive conclusions can be drawn from so superficial an analysis. The cause of Netty's soaringly high class-level structural disorder remains a mystery.