It's Evolution Time

Nein, das ist kein Bild von Gipf-Oberfrick sondern...
Beitrag erstellt am: 08.03.24
Recently we had one of our regular Area Kick-off events at Digitec Galaxus. I like this recurring event for several reasons: For one, all seven teams of our Order Management Area show what they are working on in their respective domain, giving the other teams a chance to catch up. These presentations are always funny, inspiring and interesting at the same time. And of course, there is the Kick-off party afterwards with good food, drinks and a lot of opportunities to chat and have a good time.
As Domain Architect, I am responsible for all architectural topics in our area - there is a total of six areas -- each with its own Domain Architect -- responsible for specific aspects of our business, see this article (German), if you are interested in further details: Product Development – ein bunter Haufen, der Bürokratie hasst und aus Fehlern lernt - Galaxus.

The Kick-off offers me a welcome opportunity to reach-out to all the teams in our area. Since I am given a fixed time slot of only seven minutes, and the architectural topics are vast, I usually aim for a talk that hopefully inspires and makes people think about they way they approach their daily work.
Its Evolution Time
Since this year's motto was "Its Evolution Time", I decided to talk about a topic very dear to me: How to write better software. By the way, I realized that almost twenty years ago, I wrote an article on this very topic as the basis for another presentation I held during a developer event called Cruising Java that was held on a cruise ship on lake Zurich for Credit Suisse: Some Thoughts on Better Software (Gee, I am really getting old...)

When I told a good friend about our kick-off event and my talk, he suggested to write about it on my blog: "Sascha, you haven't posted anything for some time now, so why not use this opportunity to again share your thoughts and ideas with us."

So, here we go:

My seven tips are quite universal and by no means specific to my actual work. I therefore decided to make a small series of blog posts, one post for each tip, plus an introductory post (this one) outlining the seven tips.

Programming is Easy...

... Writing software is hard, especially business software. Which suggests there is obviously a difference between mere programming and writing software.

Let's start with the obvious: Software is an asset only if it satisfies business requirements. Because requirements change, software needs to change as well, see Lehman’s Eight Laws For E-Type Programs. I picked three of those eight laws that in my point-of-view illustrate the problems and challenges of business software development quite well:

Law #1: Continuing Change

Software is never finished but merely fit for purpose. So we need ways to deal with necessary change in an orderly and timely manner. This is all about intellectual manageability and intellectual honesty: We can only change what we understand properly.

Law #2: Increasing Complexity

No matter how hard we try to avoid it, complexity grows, because the depth and breadth of our systems increase constantly. While we cannot escape essential complexity, we must strive to control accidental complexity arising from overly intricate designs or the mixing of business and technical aspects within our code bases. By the way: Software categories provide valuable insights specifically for managing the latter challenge.

Law #7: Declining Quality

If we do nothing to keep complexity at bay and if we only just add features, the quality of software declines. This is about entropy and a very specific attribute of software that real-world physical systems do not show: The Non-Locality and Proportionality Problem, i.e. small local changes in a system can proliferate into large wide-spread problems in seemingly unrelated areas of a system. More on that later.
There are many strategies, ideas and approaches to deal with change successfully. Being explicit about the way our solutions work and aiming rigorously for simplicity in our solutions are two worthwhile approaches.

Here is my all time favorite quote regarding simplicity:

Simplicity is the most difficult thing to secure in this world; it is the last limit of experience and the last effort of genius.

-- George Sand

So without further ado and to conclude this introductory post, here are my seven tips:

Tip 1: Do repeat yourself!

Repetition and duplication are not the same thing. Find some pattern or set of higher-order abstractions that you can use over and over again in your solution. This is about having simple and sound meta models that you can use to structure your software designs and implementation. Examples include CQRS and Event Modeling or Functional Core - Imperative Shell.

Read More

Tip 2: Think like an accountant!

There is a lot to learn from the way accountants deal with the many challenges in business systems. This is about keeping a book of records of all the relevant things happening in a system; about honoring time as an important design aspect; about striving for immutability and the way you deal with and compensate for mistakes that happened; and last but not least about closing the books, i.e. modeling clear life cycles for the important stuff that is going on in our business - remember the famous Cylon mantra from Battlestar Galactica: "Everything that has a beginning has an end." (Just for those wondering: While writing this, I am listening to BSG Seasons IV's soundtrack.)

Read More (To be published on 2024-05-01)

Tip 3: Forget Reuse!

Prefer code that is easy to replace. While we have mastered reuse in the small, we still fail miserably at reuse in the large. Code that is easy to replace is good code in the sense that it is explicit and shows high cohesion, i.e. it follows the Single-Responsibility Principle, it is small and composable.

Tip 4: Design for Orthogonality!

Our systems should not be like a helicopter where all steering elements are highly intertwined and somehow related. Rather, eliminate effects between unrelated things. This is about loose coupling!

Tip 5: Verbs are More Important Than Nouns!

For example, it is more important what you do with an order than what properties it seems to possess. Focusing on behavior is one key strategy for better aggregate design, giving you meaningful invariants to enforce based on what you need to do from a business point-of-view. Don't shape your aggregates by focusing on properties you think could go into the same table or class.

Tip 6: Practice Dependency Rejection!

Every dependency is a possible time bomb! Dependencies are ok at the outer parts of your systems, try to keep your core pure in the sense of Functional Core - Imperative Shell. Avoid deep dependency trees - they are a disaster waiting to happen and a big contributor to the Non-locality and proportionality problem mentioned before.

ETC - Easy to Change

At its core, these six tips are about ETC - Easy to Change. Because, Good Design is easier to change than Bad Design. Now, this is not a rule but rather a guide. And it assumes you can tell which of many paths will be easier to change in the future. Which has a lot to do with how experienced you are and whether you are able to use that experience of yours to your advantage. Which directly leads to my last tip:

Tip 7: Keep a Developer Diary!

Take some time to reflect on your daily work. Hone your skills and develop your instincts. Record your mistakes and learn from them.