Structure101 V3 Released, Adds Architecture Control for Teams

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!

An Overview of Structure101 Architecture Diagrams

Structure101 lets you work with both structure (the whole code-base as it is) and architecture (the subset of the structure that you really care about, and how it should be). It lets you define the architecture in the context of the physical structure and diseminate this to the team. Architecture diagrams are what makes this possible.

Layering and composition

Structure101 architecture diagrams use a concise visual notation for representing architectural layering and composition. Here is an example of one of the architecture diagrams that we use for the structure101 code-base.

Layeringandcomposition_3
The principle is simple; components (“cells”) should only depend on components at lower levels, not in the same or higher levels.

Layering Overrides

Sometimes a top-down dependency structure is too simple to capture the intent of an architecture. "Overrides” allow you to override the default layering of a diagram. For example we may decide to allow a specific dependency from a cell to a higher-level cell. The override is shown as a green (“allowed”) arrow on the architecture diagram. (Note that enabling this “upward” dependencies practically  merges the “hiView”, “xbase” and “graph” components from the perspective of testing, reuse, development, etc.)

Layeringoverrides
A more common example is where we wish to enforce a more strict layering. For example we may want one layer to only use the next layer down, but not layers below that. Such an override is shown as red (“disallowed”) on the architecture diagram.

Combining diagrams

It is not necessary to include all aspects of an architecture on a single structure101 architecture diagram.

A common scenario is where a number of “add-ins” are distributed across several packages. For example, this diagram shows part of the structure101 architecture.

Combiningdiagrams1
It is correct, but incomplete. Classes in assemblies.X should never depend on classes in lang.Y.  We could express this by adding several overrides, but it is much cleaner to use a separate diagram for this aspect of the architecture.

The next diagram defines a number of “language packs” that do not have a direct equivalent in the physical structure (they are “pure” architecture components), but express the architectural constraint that was missing above.

Combiningdiagrams2
The combination of the 2 diagrams defines the intended architecture.

Mapping the architecture to physical code

In order to understand how a physical code-base conforms to an intended architecture, we need to map the architectural components (cells) to physical code. 

Simple patterns are used to establish this mapping. This has a number of benefits:

  • If a diagram contains a component mapped to com.headway.lang.* and the team creates a new package com.headway.lang.cobol, then the diagram is not rendered obsolete – all the classes in the new package map to the intended component.
  • I can create components with more complex mappings with expressions such as com.headway.*.test.?
  • I can create and show a component for which no code has yet been created, either by specifying no pattern or specifying the paths where I expect the new code to be implemented.
  • I can effectively “hide” physical entities from a diagram. For example any code in com.headway.lang.cobol will simply map to a component with the expression com.headway.lang.* - I do  not need to show package cobol on the diagram if I don’t want to.

Another flexibility is that a physical entity maps to the component with the most specific pattern.  For example if I include 2 components, one with com.headway.lang.* and the other with the expression com.headway.lang.java.*, then the class com.headway.lang.java.myClass will map to the latter. The effects of this can be at the same time subtle and powerful. For example I could move the component that maps to com.headway.lang.java.* into another “parent” altogether. 

Finally, each diagram has a (possibly empty) expression that maps to  “excluded” items. This is useful if some physical entities would otherwise undesirably map to a component in the diagram.

Once the mapping is established, any dependencies that violate the architecture is shown on the diagram as a curved dotted line as shown here between component “graph” and the higher-level package “hiView”.

Maptophysical
It is easy to discover the code-level cause of a violation by selecting it on the diagram within a structure101 client or IDE plug-in.

Code Organization Guidelines for Large Code Bases

In an excellent on-line presentation Juergen Hoeller gives rationale and guidelines for controlling the structure of large, evolving code-bases. Juergen is the chief architect of the Spring framework, which as I have previously pointed out is structurally almost perfect. This didn't happen by accident.

If you don't have time go though the 88 minute presentation, here is a nice sysnopsis by Mike Nereson.

Structure101 IntelliJ Plug-in

This has just been made available for download. It displays architecture diagrams within the IDE, and warns if any code changes are inconsistent with the target architecture.

Intellijsmall

It works more or less like the structure101 Eclipse plug-in except that for now it checks for architecture violations on demand rather than automatically when you do a build.

Structure101 Supports Java 1.5

We have overhauled the byte-code parser to now pick up Java 1.5 constructs (e.g. generics and annotations), plus it is much faster.

You can download the first build that includes the new parser here.

If you currently use the structure101 IDE plug-in you may find that you get bogus warnings on "new" architectural violation when you start using the new parser. This is  because the parser is now finding a few more dependencies related to the Java 1.5 language updates, and thinks they are new compared to your reference snapshot. If it's giving you a headache, you should just republish your reference snapshot to the structure101 repository with the new parser.

Eclipse Plugin (OSGi) Visualization

If you are going mad trying to figure out the dependencies between lots of Eclipse plug-ins, or work with other large OSGi systems, you may be interested in this.

We've had a few people looking for an Eclipse/OSGi backend for Structure101, and with all the hype about OSGi lately, we decided to lift the lid on it.  Here is an early version that you can download. If you're an Eclipse user, just point it at your plugins directory to see the same kind of views, hierarchies and slices that you get with the Java version.

Below is a random screen shot of my Eclipse plug-ins to give you the idea (click for the full-size image).

It's pretty rough at the moment - the download page indicates where we've made some arbitrary decisions on the model structure and where we think it's probably not quite right. I'd love some comments from OSGi heads on if/how you'd like us to change it to make it more finished. If you think you'd find it useful, talk to Paul about an extended license key.

DevX review of Structure101

"Getting your arms (and eyes) around large, complex code bases has never been easy, but Structure101 from Headway Software may just be the elegant solution to this age-old problem. Find out how this visual design tool analyzes your enterprise projects and lets you zone in on issues quickly and gracefully."  Full Story by Derek Lane.

Complexity Debt - don't "fix it", "keep a lid on it"

So you just discovered that your code-base has racked up a whole load of complexity debt. This  maybe explains why progress seems so painfully slow lately. You briefly think of suggesting a major complexity-reducing refactoring effort. This will delay the next release significantly, but foreshorten the time to the following releases. Plus a cleaner, simpler code-base will make the world a nicer happier place, right?

But you don't suggest this. You're human and self-preservation is an instict. Precisely because of the recent slow progress, there is a lot of disapointment on the whole product delivery front at the minute. Suggesting another big delay doesn't feel like the best career move just now.

Luckily there is another, more subtle way to get to that happier place without climbing out on long limbs over thin ice.

Don't repay the debt in one big painful bang - just keep a lid on it. And watch it begin to disipate as though by magic.

You use personality, charisma, leadership and/or donuts to convince your team that henceforth, they will not add any more complexity debt to the code base. Now watch what happens...

If I need to add to a method with a CC of 20 (where the threshold is say 15) and I add a couple of new paths, then I temporarily increase the complexity from 20 to 22. Uh oh, I said I wouldn't do that. No problem - I'm working on the method already, so I have a good handle on what it does. I just extract a suitable lump into a new method with a nice helpful name and bingo, I have 2 methods each within tolerance instead of 1 over. The 2 methods are simpler and easier to understand and maintain than the 1 before, and the overall code-base debt just went down a bit. Well, I feel good about this.

But wait. That one new method pushes the containing class over the class-level complexity threshold. Again, I refactor the class while its workings are in my head already (perhaps I use move field or extract class). Again, if the class was previously over-threshold, then I probably just reduced the overall debt a bit more.

The same will happen when anyone trys to add to any overly-complex package. And as the xs framework sets thresholds at every level of design breakout, the developers are relieved of the temptation to "hide" complexity by pushing it up or down the hierarchy. The code-base becomes truly less complex, without anyone really trying.

This is cool enough to be named - how about "KALOI" for "keep a lid on it".

KALOI is supported by Structure101 and there is more explicit support in the pipeline. More on this later.

Structure101 v2 goes GA today

Additions let you see complete slices of a code-base at any level, home in on structural complexity, view dependency graphs in matrix form, and map code items and groups (like tangles) through different hierarchies, slices and perspectives (more download).

Structure101 v2 beta 2 released

Structure101 is for contolling architecture and structural complexity. Version 2 introduced slicing and tagging. Beta 2 adds dependency hiding and cross-perspective navigation.

New in v2 beta 2:

  • Context menus (right mouse click) have been added. This introduces the new capability to navigate easily between views (perspectives).
  • It is now possible to tag dependencies as well as items.
  • It is also possible to hide tagged dependencies – I.e. remove them from the model. This is useful for simulating structural changes.
  • Performance problems on Linux and Mac have been fixed.
  • Look and feel on Linux and Mac have been improved