Edmund Kirwan

About Edmund Kirwan

Edmund is a programmer with a telecoms company in Stockholm where he is currently working on a large-scale network simulator. In his spare time he thinks far too much about program-structure.

Dependency inversion: the structure logarithm

Re-examining benefits.

Through the corroded dripping pipes of transitive dependencies, ripple effects gush. Programmers sometimes spend arduous days clambering down into the darkened building-tall labyrinths of plumbing for no other reason than to rip out some of those transitive dependencies so that predictability of cost of change might improve (amplification offering prime motivation). Those programmers that return often, after lengthy recuperation, babble of ancient principles glimpsed in new garb.

Consider the spoiklin diagram of figure 1, in which three methods – a(), b() and c() – call a utility method, d(), which in turn calls five others.
 

Figure 1: A simple system of nine methods.

Figure 1: A simple system of nine methods.

How many transitive dependencies appear in figure 1? This essentially asks how many ways we can fall from the top to the bottom row. From a() there is only one path, to d(), but from d() five possible choices exist. Method a() can reach the bottom in five ways:

  • a() → d() → e()
  • a() → d() → f()
  • a() → d() → g()
  • a() → d() → h()
  • a() → d() → i()

Thus there are five transitive dependencies reaching from a() and the same amounts from b() and c(), giving a total of 3 x 5 = 15. In general this configuration, where n elements depend ultimately on m elements, generates n x m transitive dependencies.

Now consider that the programmer wishes to further keep de-couple the three client methods from the implementation of the utility method, d(). To do so, the programmer unsheathes the glittering dependency inversion principle and slashes a new interface with an abstract d() method which a concrete class will then implement. Figure 2 shows the resulting system.

Figure 2: Dependency inversion.

Figure 2: Dependency inversion.

In figure 2, the same three methods – a(), b() and c() – call utility method d() below but now via the new interface. The concrete class implementing the utility method also has a d(), one on which no dependencies fall (clients invoke the interface method, not the concrete method) so that the concrete d() appears on the top row, a dashed-line showing its inheritance dependency on its corresponding interface method below.

How many transitive dependencies does figure 2 contain? All four methods on top terminate on the abstract d() below, yielding four transitive dependencies. Concrete method d() above also has five dependencies on the original bottom-row methods, bringing the total number of transitive dependencies to nine.

Note, however, that a fundamental structural change has taken place. The number of transitive dependencies can be now expressed as a sum rather than a product. That is, the original system generated 3 x 5 transitive dependencies; the new system generates 3 + 6 transitive dependencies. In general we can say that where n original elements depend ultimately on m original elements, the above dependency inversion will reduce the number of transitive dependencies from n x m to n + m + 1. If n and m are large, this can be a significant saving.

Just as mathematical logarithms help ease calculation burden by reducing a product to an addition, so too can the dependency inversion principle help reduce the number of transitive dependencies from a product to an addition. Furthermore, this application of the dependency inversion principle has also reduced the system’s depth, “depth” being the average length of the system’s transitive dependencies. In figure 1, all the transitive dependencies are of length three; in figure 2, they are all two elements long. Given that ripple effects cause most destruction when wormed deep in a vast profusions of transitive dependencies, the dependency inversion principle would seem a double benefactor.

Summary

Old crotchety principles sometimes surprise. The dependency inversion principle has long earned respect from programmers for its prowess at smashing the rigidity and fragility of otherwise un-lubricated systems. Yet this fails to map the full extent of its powers. Seen from a purely structural perspective, it can be used to reduce both the number and length of transitive dependencies squirming through a program.
 

Related Whitepaper:

Software Architecture

This guide will introduce you to the world of Software Architecture!

This 162 page guide will cover topics within the field of software architecture including: software architecture as a solution balancing the concerns of different stakeholders, quality assurance, methods to describe and evaluate architectures, the influence of architecture on reuse, and the life cycle of a system and its architecture. This guide concludes with a comparison between the professions of software architect and software engineer.

Get it Now!  

Leave a Reply


7 − two =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books