Author Archive
An often overlooked extension to Structure101 is the “Headless” mode of operation. This lets you hook s101 into your nightly build so that it checks for things like newly introduced complexity or architectural rules being violated while you sleep. You specify what you want checked, and whether you want to break the build or just receive a warning.
Eran Harel (“Code Slut”) has blogged how he uses this in Orbitz.
Architecture Diagrams in Structure101 are mapped to the physical code by patterns associated with each cell in the diagram. This enables the visual specification of rules that can then be applied to a specific version of your code so that Structure101 can overlay any violations on the diagram and let you discover the offending code items.
When you let Structure101 create the diagrams for you, and stick to changes like adjusting the layering, expanding packages, or moving packages to new parents, etc., you can mostly leave it to Structure101 to handle the patterns. However, occasionally you may see some behavior that seems odd unless you understand how patterns interact. And of course you may want to take advantage of the more advanced capabilities.
A key aspect that is not obvious at first is the “most specific pattern” rule. This says that where a physical class maps to more than one cell, the Architecture Diagram associates the class with the cell that has the “most specific” pattern.
Here’s an example diagram which was automatically generated from part of the Findbugs code-base:

… and here is the same diagram showing the pattern associated with each cell:

If I have a code-base that happens to contain a class edu.umd.cs.findbugs.classfile.impl.ClassFactory, then that class matches the pattern associated with the cell called ClassFactory. However it also matches the patterns for both ancestor cells “impl” and “classfile”. Since the ClassFactory cell’s pattern is the most specific (no wildcards), that is the cell to which Structure101 associates our physical class. And since a class is associated with at most one cell, that class is not associated with either ancestor cell, even though it matches their (less specific) patterns.
As expected, here are the associated items that Structure101 reports for the ClassFactory cell:

… and the parent “impl” cell:

Now I delete the 3 inner cells so that the diagram looks like this (the patterns for the remaining cells are unaltered):

Since the cells with the more specific patterns are gone, the classes that were associated with them now match the next most specific pattern – the parent “impl” cell:

This can be puzzling – I click on the “expand” button, the child cells are added to the diagram (which I expect), but the list of items associated with the parent is suddenly empty (which I don’t).
Why would we do it this way? We figured it was the best way to be future proof (the wildcards handle any added/removed classes) while at the same time supporting refactoring (e.g. if I move a class to a new package, the most specific pattern goes with it, but all the other classes still match to the original parent).
“Go” is a new systems programming language created by Google. Syntax is based on C++, and it compiles (like greased lightning apparently) – even has a Printf()! But beyond trivial similarities it is a very different beast:
- Interfaces replace class inheritance, but unlike Java interfaces, no explicit reference to the interface is required – as long as a type provides the methods named in the interface, it implements the interface.
- Garbage collection.
- Arrays are first class citizens – you don’t need to (can’t) use pointers to access the elements – instead you use [], and “slices”.
- A “slice” is a section of an array and behaves very much like an array – you can create a slice of a slice.
- Strings are first class and immutable, so memory allocation is not an issue.
- “Maps” are hash tables and are also first class.
- Threading is part of the language (no RTOS needed). “Goroutines” run in parallel and communicate via “channels”.
- No header files (that would have ruled it out of my book). “Packages” are used to group and reference (“import”) stuff.
- Reflection.
- Type conversion is explicit, no function overloading (that’s an odd one – presume it’s to speed up compile time – expect a lot of awkward function names), no user-defined operators.
Google reckon it’s “fun” to use. Compared to C++ that’s presumably a no-brainer – I’d say Java programmers would probably take to it as easily. Assuming it does what it says on the can.
From a dependency management point of view, I don’t much like the implicit (read “hidden”) implementation of interfaces. But I like the absorbsion of concurrency into the language – should allow modelling of references that disappear into the OS in C++. But it’s not ready for primtime yet – it’ll be a while before we go building a Go backend for Structure101…
Just got back from SD West and unpacked our Jolt Productivity Award. Huge credit and thanks to all the users that provided the stream of feature suggestions that has contributed to making Structure101 such a great product. And congratulations to the product and development team at Headway who spent so many tortuous hours discussing and honing each new feature (sometimes politely!) so that the product stayed usable as it got deeper.
… in the Design and Modeling category. Yeah!
Press release
Just released, Version 3.1 adds lots of new stuff to the Architecture perspective to make it much easier to discover the current structure and move classes or packages around to define a preferred architecture.
First thing is a simple expand and collapse button on each cell. So for example you can ask Structure101 to create a high-level architecture diagram from the current code-base – no need to worry about how deep to make the initial diagram since you can now expand and collapse cells once you have the initial diagram.
Let’s say you get the following diagram:

This shows a layering violation from the strut2 package to the dispatcher package. Click the “+” to find out what is being used at the next level of detail.

So something in struts2 is using something in dispatcher.controller. Expand both cells…

And we see there is a single class-to-class dependency causing the violation. Also, since the Dispatcher class is below the other classes in the dispatcher.controller layering, we know that the other classes use, but it does not use the other classes. And the layering in the struts2 package indicates that we can move Dispatcher to the indicated level to fix the violation without creating new ones. Just drag and drop Dispatcher to create this:

Collapsing the 2 top-level cells by clicking the “-” icons shows the original layering but with the underlying code rearranged so there is no longer an architecture violation.

Other stuff that has been added in this version:
- Once you have moved classes or packages, you can get a list of all the moved items.
- You can convert the list of moved items into transformations on the underlying model. This lets you iterate on a restructuring job – use an architecture diagram as a kind of “Sandbox” until you have some set of changes you’re happy with, then convert them into transformations and start sandboxing the next set of changes.
- You can now apply strict layering to a diagram. This means that cells can only use cells immediately below them, not below that.
- You can show any dependencies (i.e. not just violations) either on the whole diagram or on selected cells.
- You can drag items onto an architecture diagram from the dependency breakout.
Final note, if you are using the architecture diagrams to drive your developers, you should choose the expansion level of cells consciously before publishing them to the project repository. Their code changes will be checked against the visible levels only.
I have updated the architecture diagrams for the just-released Spring 2.5. Any new or changed packages are highlighted (since 2.0.6). The diagrams are also online – if you pointed your IDE plugin at these after my previous entry, you will be seeing the updated diagrams in your IDE already, and any compile time messages about architecture violations will be based on the new versions.
Here’s the new top-level architecture:

And here are the internals of the larger subsystems:
org.springframework.aop:

org.springframework.beans:

org.springframework.jdbc:

org.springframework.jms:

org.springframework.orm:

org.springframework.web:

Released today, the new version 3 capabilities make Structure101 a nicely rounded architectural control solution in addition to the previous structural analysis and complexity measurement capabilities.
For example:
- You can now define layering constraints on your code-base using simple, intuitive architecture block diagrams
- Communicate these architecture diagrams to the development team through IDE plug-ins
- Developers get warned immediately if they make code changes that are inconsistent with the architecture
- RSS activity feeds let you know if new architecture violations make it into a build
Also, there’s a new online demo (about 13 minutes, with audio (me!)) and the version 3 Help is available online.
Full press release
Enjoy!
A lot of work went into this. A "periodic table" of visualization methods for data, information, concepts, strategy, metaphors, process and structure.
Here’s a screen shot – be sure and visit the original if you’re interested – when you mouse over each cell, you get an example of the corresponding visualization method.
I didn’t see any of the visualization techniques used by structure101 for visualizing software dependencies and architectural layers. It is more focused on business processes, though Data Flow (Df), Entity-relationship (E) and Flowchart (Fl) diagrams are there.
Java packages are often used like file-system folders to organize source. But source files differ from “normal” files in that they are highly inter-dependent. Considering this interdependence as a package hierarchy evolves can have significant productivity benefits.
Packages as Folders
Java packages provide an ideal way to organize code into a scalable, hierarchical structure that helps us find specific code.
In this sense, packages can be used like folders in a file-system:
- We place files with something in common in the same folder.
- When a folder grows too big and we find we’re having trouble finding files, we split the folder into sub-folders according to some criteria that makes sense to us.
- We share files by placing them in a common area on company network, in which case the structure evolves according to the varying criteria of different people.
- We often have trouble deciding which folder a file best belongs, and make an arbitrary decision.
Often Packages are only used as a kind of filesystem equivallent. However the package hierarchy can also be used to reinforce the intended design and associated development activities.
Packages as Design Abstractions
Source files differ from other files typically stored in the file-system:
- They depend on the detailed contents of other source files.
- Are created and edited in groups of multiple files.
- Are subject to a high number of relatively small changes.
- Are edited by a team of developers rather than individuals.
- Should be reusable on future projects.
- Should be easy to change without impacting other files too widely.
- Must support the defined deployment environment.
- Are subject to a QA, version control and release processes.
The aim of a package design should be to support these characteristics. For example, the design could explicitly support Martin’s “Reuse/Release Equivalence Principle (REP)” (article, book) whereby packages are developed, built, tested and released against released versions of the packages upon which they depend.
Design is not something that happens once at the start of the project – it is an activity that spans the life of an application or product. This fact has become explicit with the iterative and Agile development models. As the code-level design continues, the package-level design emerges.
Unfortunately, the emergent design is often invisible and so forgotten. Not only does the original design degrade, but the overall structure tends to become excessively complex. As the supporting structure dissolves, development activities become harder and the cost of each new feature increases.
This priciple of emergent design is important here. Clearly when I have a project of 50 classes in a half-dozen packages, the overhead of a sub-optimal package dependencies isn’t going to slaughter me. But if my project is going to grow to 5000 classes, then putting in minimal effort from the start can save huge effort when things get more complicated.
In part 2 I’ll take a closer look at cyclic package dependencies and why they matter.