You probably never heard about “Code Cancer”, but this term would be an adequate description for some key issues most non-trivial software systems are suffering from. Chances are that your own organization is affected by it right now. In this article I will describe what I mean by “Code Cancer” and offer ideas how to mitigate this problem.
Read MoreCategory: Software Architecture
Motivation for Code Quality
The main idea behind Sonargraph has always been to provide a tool that eases the creation and maintenance of high-quality software. For any serious project that must live longer than a couple of months, it is actually cheaper to spend a part of your resources to keep your software constantly at a good level of quality than using all your time to create new features. Martin Fowler explains this very well in his article “Is High Quality Worth the Cost?”. The bottom line is, that apart from the very early development stages, high-quality software is actually cheaper to develop, because it allows adding new features at almost constant speed, whereas it becomes more and more time consuming to add new features into a code base with low quality. According to our experience the most successful teams spend about 15% to 20% of their time on code hygiene.
We at hello2morrow believe that a consistent architecture is a fundamental part of software quality. When we use the term “architecture”, we think of it in terms of the IEEE 1471 standard:
“The fundamental organization of a system embodied in its components, their relationships to each other, and to the environment, and the principles guiding its design and evolution.”
This blog post describes why architectural design as an activity is needed, why conformance checks need to be done automatically by a tool and how Sonargraph supports you as a developer and architect during these activities.
Read MoreVisualizing an Architecture Aspect as a UML Component Diagram
Sonargraph’s domain specific language (DSL) to describe architecture aspects is very powerful. An architecture aspect consists at least of 1 top-level architecture file that has been added to the architecture configuration and is checked automatically. Such a top-level architecture file can include other architecture files reusing common definitions. With our latest release (11.4.0) we complemented the strictly text based representation of architecture aspects with a UML component generator.
A generated UML component diagram complements in several ways our text based architecture aspects:
- It is a commonly accepted form of communicating architecture definitions
- It shows the resulting architecture aspect event if it is spread over several files in 1 diagram
- It can be used to cross-check the underlying text based architecture aspect (i.e. are the resulting restrictions the intended ones?)
Analyzing Software with Advanced Visualizations
I thought I’d use our new 3D city view visualizations to have a closer look at Apache-Cassandra, a very popular and successful open source project that implements a NoSql database. I know from previous analysis runs of the same software that it already had problems with structural erosion. Years ago I analyzed Cassandra 1.2.6 and found pretty big cycle groups for Java files as well as for packages. Maintainability Level was only 9.4% (everything under 50% is concerning) while the metric “Propagation Cost” has a value of 62%. That means that every change will affect 62% of all code directly or indirectly which also is not a good thing because it significantly increases the chance of regression bugs.
Before you say “this image is useless, you cannot see anything there” let me tell you that I agree. The point is to make sure that your software never ends up in that situation. This big cyclic conglomeration is making it close to impossible to modularize Cassandra or to put any kind of architectural model on top of it.
Read MoreDesign Architecture Improvements using Sonargraph’s Architectural View
In the last couple of months we added support for the interactive modeling of architectural aspects in Sonargraph. Whilst our architecture DSL is tremendously powerful, there are situations where the new interactive modeling via the Architectural view is more appealing.
The Architectural view is is ideal for exploring architecture, designing architectural aspects and simulation of code refactorings on existing (even unfamiliar) code bases. Its power is derived from the unique combination of code exploration, architecture definition, simulation of code refactorings and visual feedback of architectural issues in real time.
For this blog post I chose FreeMind as example project, a freely available software written in Java offering a user interface based on Swing/AWT. The hypothetical task at hand is to see what needs to be done to implement another user interface based on let’s say SWT. The author of that popular free mind-mapping software probably never envisioned this requirement, but we have all seen frameworks come and go, so this is not a far-fetched requirement and is obviously not limited to SWT. I picked the software solely as an example to demonstrate how Sonargraph’s Architectural view helps to prepare the existing code base for such a task.
Read MoreA Promising New Metric To Track Maintainability
A good metric to measure software maintainability is the holy grail of software metrics. What we would like to achieve with such a metric is that its values more or less conform with the developers own judgement of the maintainability of their software system. If that would succeed we could track that metric in our nightly builds and use it like the canary in the coal mine. If values deteriorate it is time for a refactoring. We could also use it to compare the health of all the software systems within an organization. And it could help to make decisions about whether it is cheaper to rewrite a piece of software from scratch instead of trying to refactor it.
Read MoreUsing Annotations or other Criteria for Architectural Models
Sometimes the information needed to properly assign a component to an artifact is not part of its architecture filter name. Imagine for example a code generator that generates classes for different functional modules. If all those classes end up in the same package it becomes very hard to assign the generated classes to the right functional modules unless the class name contains some clue. If those generated classes could be properly assigned based on an annotation that would be a far more effective method of assignment.
Logical Architecture Models
With Sonargraph 9.7 our architecture DSL gets a new feature: logical models. Up to 9.7 the concept of a component (the smallest unit assignable to an architectural artifact) was based on the physical layout of your project. So components in a physical model are based on source files and their relative location in the file system. In a logical model components are the top level programming elements in a namespace or package and their name contains the namespace and no relative path.
Adding Transitive Dependencies to the Architecture DSL
This post assumes that you are already familiar with Sonargraph’s architecture DSL. If not, I recommend first reading “how to organize your code”.
Transitive dependencies are a useful addition to formal architecture descriptions. The following example shows a typical use case:
artifact Controller { include "**/controller/**" connect to Foundation } artifact Foundation { include "**/foundation/**" }
Here Controller
depends on Foundation
. We also assume that classes from Foundation
are used in the public interface of the controller classes. That means that each client of Controller
must also be able to access Foundation
.
artifact ControllerClient { include "**/client/**" connect to Controller, Foundation }
This is certainly not ideal because it requires the knowledge that everything that uses the Controller
artifact must also connect to Foundation
. It would be better if that could be automized, i.e. if anything connects to Controller
it will automatically be connected to Foundation
too.
With Sonargraph 9.6 this is now easy to implement:
artifact ControllerClient { include "**/client/**" connect to Controller // No need to connect to Foundation explicitly } artifact Controller { include "**/controller/**" connect to Foundation transitively } // ...
Using the new keyword transitively
in the connect statement will add Foundation
to the default interface of Controller
. That means that anybody connecting to the default interface of Controller
will also have access to Foundation
without needing an explicit dependency.
The new keyword only influences the default interface. For explicitly defined interfaces the transitive export also has to be made explicit:
artifact ControllerClient { include "**/client/**" connect to Controller.Service // Will also have access to Foundation } artifact Controller { include "**/controller/**" interface Service { include "**/service/**" export Foundation // Transitive connection must be explicit } connect to Foundation transitively // only affects default interface } // ...
Before we had transitive connections an interface could only export nested artifacts. Now interfaces can also export connected interfaces. In the example above we add the default interface of Foundation
to the Service
interface of Controller
. Exporting interfaces that are not a connection of he parent artifact will cause an error message.
This feature is available with Sonargraph 9.6 or higher. Let me know what you think about it in the comment section below.
Designing Generic Architectures Using Templates
Many companies already have some established architectural design patterns which are supposed to be used in most of their applications. For example it makes sense to standardize the layering of business components. It also makes sense to establish specific rules how one business component can access another one. In the upcoming 9.4 release of Sonargraph-Architect we implemented a new feature in our architecture DSL which should make it very easy to add generic architectural blueprints to a quality model which would allow automatic verification of those architectural design patterns on any business component without having to create a component specific architecture.