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.
The principle is simple; components (“cells”) should only depend on components at lower levels, not in the same or higher levels.
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.)
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.
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.
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.
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”.
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.