Evolving Sonargraph’s Architecture DSL

Sonargraph’s architecture DSL is now about 18 months old and we received a lot of positive feedback from customers bundled with ideas for improving the language. There are now several projects with more than one million LOC that use this language to define and enforce their architectural blueprint. Of course this feedback is most valuable for us and we did our best to implement a good share of the ideas brought to us. This article requires some basic knowledge of our architecture DSL. An introduction can be found here. To use all the features described below you need Sonargraph-Architect version 9.3 or higher.

Expressing Architectural Patterns as Artifact Stereotypes

There are some basic patterns that are used in almost every architectural model. Those patterns describe the relationships between sibling artifacts, i.e. artifacts that have the same parent.

  • Layered architecture – here dependencies are allowed to flow top-down within an ordered list of sibling artifacts. If we use strict layering, an artifact can only access ist next sibling artifact. In the case of relaxed layering, artifacts have access to all artifacts defined beneath them.
  • Independent – here sibling artifacts are independent from each other, i.e. there should be no dependencies between them.
  • Unrestricted – here siblings artifacts have no restrictions in accessing each other. This is not very desirable because it will allow cyclic dependencies between artifacts, but can be really useful when working on a model for a legacy software system.

Read More

How to Organize your Code

In this article I am going to present a realistic example that will show you how to organize your code and how to describe this organization using our architecture DSL (domain specific language) implemented by our static analysis tool Sonargraph-Architect. Let us assume we are building a micro-service that manages customers, products and orders. A high level architecture diagram would look like this:

System Architecture

It is always a good idea to cut your system along functionality, and here we can easily see three subsystems. In Java you would map those subsystems to packages, in other languages you might organize your subsystem into separate folders on your file system and use namespaces if they are available.

Read More

Meet the Sonargraph Gradle Plugin – and Say Goodbye to JDepend

With the release of Sonargraph 8.8.0 today we also released the first version of our brand new Gradle plugin. It allows you to create reports for any Java project, even those that do not have a Sonargraph system specification. This is a quick and easy way to get some metrics and other findings like circular dependencies about your project. In this article I am going to show you, how you can use our Gradle plugin to make your build fail if your system contains cyclic package dependencies. Believe it or not, there are still people out there that use JDepend for this very reason (I did too, but that was more than a decade ago). Since you can do everything I am describing now with our free Sonargraph-Explorer license including the interactive visualization of cycles, I think you won’t regret saying “Good Bye” to JDepend and “Hello” to Sonargraph. Read More

Designing a DSL to Describe Software Architecture (Part 3)

Connecting Complex Artifacts

After having covered the basics and some advanced concepts in the previous articles this post will examine the different possibilities to define connections between complex artifacts. Let us assume we use the following aspect to describe the inner structure of a business module:

// File layering.arc
exposed artifact UI 
{ 
    include "**/ui/**"
    connect to Business 
} 
exposed artifact Business 
{ 
    include "**/business/**"
 
    interface default
    {
        // Only classes in the "iface" package can be used from outside
        include "**/iface/*"
    }
 
    connect to Persistence
} 
artifact Persistence 
{ 
    include "**/persistence/**" 
}
exposed public artifact Model
{
    include "**/model/**"
}

This example also shows a special feature of our DSL. You can redefine the default interface if you want to restrict incoming dependencies to a subset of the elements assigned to an artifact. Our layer “Business” is now only accessible over the classes in the “iface” package. Read More

Designing a DSL to Describe Software Architecture (Part 1)

Software architecture defines the different parts of a software system and how they relate to each other. Keeping a code base matching its architectural blueprint is crucial for keeping a complex piece of software maintainable over its lifetime. Sure, the architecture will evolve over time, but it is always better to have an architecture and enforce it than giving up on keeping your code organized. (See my recent blog post: Love your Architecture)

The problems start when it comes to describing your architecture in a formal and enforceable way. You could write a nice Wiki article to describe the architecture of your system, or describe it on a Powerpoint slide or with a set of UML diagrams; but that would be quite useless because it is not possible to check in an automated way whether or not your architecture is respected by the code. And everybody who ever worked on a non-trivial project with more than 2 developers knows that rules will be broken. That leads to an ever increasing accumulation of architectural debt with all kinds of undesirable side effects for the long term sustainability of a piece of software. You could also use Sonargraph 7 or similar tools to create a graphical representation of your architectural blueprint. That is already a lot better because you can actually enforce the rules in your automated builds or even directly in the IDE. But it also means that everybody who wants to understand the architecture will need the tool to see it. You also will not be able to modify the architecture without having access to the tool.

Wouldn’t it be nice if you could describe your architecture as code, if you had a DSL (domain specific language) that can be used by software architects to describe the architecture of a system and that is expressive and readable enough so that every developer is able to understand it? Well, it took us a while to come up with that idea, but now I believe that this is the missing puzzle piece to significantly boost the adoption of formalized and enforceable software architecture rules. The long term benefits of using them are just to good to be ignored.

Read More

Love your Architecture

The single best thing you can do for the long term health, quality and maintainability of a non-trivial software system is to carefully manage and control the dependencies between its different elements and components by defining and enforcing an architectural blueprint over its lifetime. Unfortunately this is something that is rarely done in real projects. From assessing hundreds of software systems on three continents I know that about 90% of software systems are suffering from severe architectural erosion, i.e. there is not a lot of the original architectural structure left in them, and coupling and dependencies are totally out of control. Read More

The Importance of Defining “Done” Correctly

The nicest thing you can say to a project manager or your boss is something like “I am done with my task / project“. Everybody loves people who are getting things done. If you do that consistently you will get rewarded and used as an example for those other slackers who are having a bit more trouble with getting things done. On the other hand people who write beautiful, elegant and maintainable code hardly ever get any recognition for that. Nobody really seems to care about the “internals” as long as the software somehow does what it is supposed to do. In a cultural environment like this technical quality, code maintainability and sustainability in general are easily thrown under the bus. Read More

Not all Technical Debt should be Treated Equally

The metaphor of technical debt is gaining more and more traction. Originally Ward Cunningham used the term for the first time in 1992, describing it like this:

“Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite… The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise.”

It is quite interesting to see that many promoters of agile development approaches now consider an ongoing management of technical debt as critical for the development of high-quality and maintainable software. This challenges the idea that development decision should almost exclusively be driven by business value because it is quite hard to assess the value of paying back technical debt or investing time into a solid software architecture. It seems to me that the value of managing technical debt and a solid architectural foundation increases more than linear with project size. If your project is just a couple thousand lines of code and the team is just 2 or 3 people  it is relatively easy to add architecture on demand by continuous refactoring. But as soon as we have tens of thousands of code lines, ongoing development of new features and larger teams things become a lot more complicated. In this case the management of technical debt and investments into a solid architectural foundation pay big dividends, as described thoroughly in this research paper.

The problem is how to measure technical debt and focussing on the right kind of technical debt. I will first discuss measuring of technical debt and then delve into the different categories of technical debt and their impact on project outcomes.

Read More