Restructure101 for Java
Franco Martinig, Martinig & Associates, http://www.martinig.ch/
Restructure101 is a tool that allows refactoring a software architecture in a sandbox environment without risks, removing unnecessary complexity and dependencies. The end result is an action list, exported to the IDE, that will guide developers in the improvement of the actual codebase.
Web Site: http://www.headwaysoftware.com/
Version Tested: Restructure101 for Java 1.0 Build 1235, tested on Windows XP, period from May to June 2011
System Requirements: Restructure101 runs on Windows, OS/X and Linux/Unix platforms
License & Pricing: Commercial, but free for open source projects, price $900 per user
Support: Email support and free upgrades are priced at $250/year
Software Architecture Problems
Even when it has been well conceived in the beginning, maintaining the quality of software architecture is not obvious. Trade-offs are made to achieve short-term schedule objectives and team turnover often leaves people working in the maintenance phase with little knowledge of the initial architectural principles. This gradual loss of the architecture's quality is represented by "technical debt" or "architecture decay". Although a team should not necessarily try to achieve a completely "clean" status of their architecture during project development or software maintenance, the deterioration of the architecture's quality over time could lead to a situation where the evolution of the system is no longer cost-effective (too much "technical debt"). Developers don't control anymore the consequences of their modifications, as the relationships between the system components are so complex that it is difficult to evaluate the side effects of any change to the codebase. A situation often made worse by the absence of post-change control using existing regression tests.
Software development teams usually try to tackle this problem with code analysis tools. Headway Software itself supplies also a tool called Structure101 that fits in this category. These tools act as a diagnostic tool on the code base, trying to find issues like code dependencies, code duplication or dangerous code.
Restructure101 provides a complementary vision to code analysis. Based on a diagnostic of the architectural quality of an application, it allows improving the software architecture using a heuristic process of exploratory changes to the structure of the application in the Restructure101 sandbox. Restructure101 doesn't work on the coding quality of your Java application, but rather on the packaging aspect of your system through the binaries. It is naturally possible to visualise the code behind the package.
The Levelized Structure Map (LSM)
The main tool used to visualise the application architecture is the Levelized Structure Map (LSM). In this model, items (Maven POMs, jars, packages and classes) are levelized into rows, or levels, so that every item depends on at least one item on the level immediately below it. Items in the same row do not depend on each other (unless there are cyclic dependencies), and items on the lowest level do not depend on any other items at the same scope. This arrangement conveys a lot of dependency information so that most of the item-to-item dependency can be hidden without loss of context.
The manipulations of the LSM in a Restructure101 sandbox are aimed at solving the following type of problems (in the order of importance as emphasised in the tool):
* Tangling or cyclical code dependency
Code dependency occurs when a portion of your code depends on code located elsewhere to achieve its functionality. A high level of dependency makes it more difficult to change your application, as the impact of changes has to be assessed in all the dependent code. A circular dependency occurs when two modules are mutually dependent, often indirectly though a chain of other modules. The Levelized Structure Map offers additional value in the analysis of dependencies as it should make it easier to compare the dependency level of a module with its conceptual location in the architecture: lower level modules in the data access layer should have less dependencies than high level modules in the user interface layer.
Dependency graph of a package tangle
LSM of the same package tangle showing "feedback dependencies"
Fat is too much complexity at any point of design breakout, for example the number of sub-packages in a higher level package, too many classes included in a package or too many methods in a class. Design items naturally accumulate an increasing number of contained items as a code base grows. When fat exceeds a complexity threshold, it is a good idea to perform a step of incremental design to split it into smaller abstractions that are easier to understand and extend.
Packages whose child dependency graph (of subpackages and/or classes) contain disconnected groups of items having low cohesion. Especially where the separate groups of items have divergent dependencies, it may make sense to split the package to better represent the true abstractions it contains.
* Mixed packages
These are packages that contain both sub-packages and classes, with dependencies between them. Architects sometimes deem this mixing of abstraction levels undesirable and moving the classes into new or existing sub-packages as indicated by their dependency level will give a consistent level of abstraction within the parent package.
This product review is focused on the Java version of Restructure101, but the same tool allows a similar approach on .NET, PHP or Actionscript systems, and C/C++ through Headway’s partners: Coverity and Programming Research.
To examine a new application, you create a sandbox indicating where the jar files are located. A number of options allow you to choose how your want to see the packages interactions, the level of detail, if you want to include external libraries and if you want to be able to visualise the source code in the case you want to access it. These properties can be changed after importing the model. Besides local projects, you can also work with architecture stores in a repository, either on a local file system or on the web. You can create an indefinite number of sandboxes in which to experiment with refactoring your codebase. Sandboxes can be duplicated if you want to save a particular state of your refactoring activity.
After parsing the packages, Restructure101 will give you a first diagnostic on the level of tangling and fat of the application and present a high level LSM. The left side of the tool shows you the diagnostic of your recent actions, a number of navigation lists including tangled packages and fat items. Within the LSM, you can double-click on an item to open or close it. You can perform a number of refactoring actions for example dragging a class to another package, which immediately shows the effect that action will have on the LSM (which is re-levelized) and records the action in your left column.
The right column contains configuration switches that allow mainly modifying the display of dependencies on the LSM. For example sets of cyclically dependent items can be grouped into a single higher-level component. In your LSM diagram you can manipulate the existing packages and classes of your application (rename, delete, move) and add new items. The following example shows the result of applying such actions to a highly tangled code base. The following is an LSM of the initial state, expanded to show several levels of nested cycles. The upward arrows are "feedback" dependencies that are causing the packages to be cyclically dependent and preventing the chart from being fully levelized.
The information panel on the left of the UI shows that almost all of the code in this code-base is involved in package tangles, and the tangled packages are listed. There are no fat items in this example.
After a couple of hours, a sequence of manipulations that removed all package cycles was discovered and the LSM looked like this:
There are no package feedback dependencies and therefore no red zones: all the dependencies flow downward. This makes the architecture much easier to understand and the impact of changes more predictable. You can see on the chart above the possible impact of making a change to classes in the com.icesoft.faces.env package. The impact on the structural over-complexity of the code-base with each refactoring action is shown on the chart below:
The temporary increase in the Fat dimension happened when the existing package structure in one region was "flattened". This removed the associated tangle but resulted in a large number of classes in a single package. When the classes were packaged up without re-introducing cycles, the over-complexity was reduced to the origin.
The 62 refactoring actions retained the existing package structure as much as possible with totally new packaging being created where the existing packages seemed hopelessly tangled. This strategy would help reduce the impact on the developers’ understanding of the code base. If this were not important, creating a new package structure bottom-up from the classes, using the Restructure101 automatic grouping feature would be an alternative and possibly easier strategy.
If Restructure101 automatically constructs the initial hierarchies from the binaries, transformations give you almost unlimited control over the structure of your model. You can specify a number of expressions that modify the fully qualified names of the classes in your project, in effect moving them to locations other than their physical locations in the code-base. You specify the transformation of a number of items that matches a certain pattern into a new output, which allows you to merge or split easily physical packages that constitute a single logical package (e.g. API and implementation packages).
The final action list can be exported to Eclipse and IntelliJ so that developers can actually implement it and improve the architecture of the application.
Behind its simplicity of manipulation, Restructure101 for Java offers a powerful mechanism to explore and modify the architecture of a Java application without any risk. Restructure101 makes it possible to salvage a decayed architecture with minimal effort. Once it is well structured, the architecture can be pro-actively defined and enforced using the complementary Structure101 product. It is not easy to quantify the benefits, but experience suggests that a well-structured code base with a defined architecture is a lot more efficient to extend and maintain than the proverbial Big Ball of Mud.