Onion, Hexagonal, Clean, or Fractal Architectures aim to organize how we deal with dependencies in our software architectures. But which one should we choose? After distilling the essence of each approach and comparing the advantages and challenges, I’ll show how to combine all of them into an approach to use evolutionary steps towards an architecture that fits your needs from day one until the software dies. You’ll see that layers and slices aren’t enough. A modularisation that fits the domain...
Evolution of Software Architectures
Evolutionary software architecture has gained much traction lately—at least in my bubble. It is one of my favourite topics, and I have presented and conducted workshops on it for over a decade. So, let me add a thought to the discussion:
The evolution of a software architecture has three dimensions:
Technical evolution,
conceptual evolution, and
the evolution of business capabilities
The Story of a bug hunt
Let me tell you a story about an adventure. An adventure that has kept me busy for the past two weeks and fortunately cumulated in a happy ending. It’s the story of the biggest and longest bug hunt of my career. It all started around May 20th, when our support department reported that customers were having trouble loading our dashboard. The issue occurred very rarely and was limited to individual users. Refreshing the page didn’t help. However, when the support team tried to...
(Mis)estimation – why estimates tend to be wrong
Our Experience with Bi-temporal Event Sourcing
Bi-temporal event sourcing combines storing data as a sequence of events, which tell what has happened with the data, and the data has two associated points of time, one when the data entered the system and one when the data takes effect. This post is about our 8+ years of experience with bi-temporal event sourcing, along with code samples showing how to achieve this. Feel free to skip the code blocks and just read the conceptual parts. But you’ll miss the beauty of F# 😂 This post is part...
Angular Signals – When should I use what?
In my last article, I explained how our communication with the backend takes place and how we were able to build a very simple caching mechanism thanks to signals. In this blog post, I would now like to demonstrate how we use the signals from our services within the components. Views As mentioned in the previous post, we have, broadly speaking, “Views” and “Actions” for displaying data from the backend. In the Views, primarily only data is presented, and in Actions, this...
Angular Signals – How to reuse Backend Results?
After explaining in the last blog post what Angular Signals are and how they are used, I would like to delve into how we at calitime.ch handle Signals to keep our tool TimeRocket soaring through the cosmos in this article. We don’t use HTTPClient! First and foremost, I must start with a circumstance that may not be common for many teams using Angular: We do not use HttpClient (anymore).Normally, HttpClient is the preferred tool in Angular to make HTTP requests to a server. It returns...
Angular Signals – How to use them in a simple way?
What are Signals? On May 3, 2023, Angular 16 was released, introducing the possibility to use Signals. Signals are another way to implement the reactive programming paradigm in Angular. For quite some time, RXJS has been available for this purpose, and it doesn’t seem to be disappearing from the Angular world anytime soon. Generally, the current consensus is that RXJS should be used for more complex problem scenarios since it is more powerful but also harder to grasp. However, for simpler...
Myths about F#: Code without type annotations is hard to review! No, it’s a relief.
After one of my presentations about F#, we had a discussion about the effect of type inference, resulting in almost no type annotations, on code readability and reviewability. The concern was that it makes the code harder to understand, especially when reviewing code, for example, outside of an IDE (GitHub/Azure DevOps/… Pull Requests).
So is there a problem or not? Let’s see.
Version Conflicts with NuGet Packages
Yesterday, I found myself face-to-face with a rather peculiar phenomenon that managed to consume a good hour of my time. As is often the case, the solution turned out to be surprisingly simple. With the intention of documenting this for future reference (especially for my future self), I am writing this short blog post. What happened? A colleague of mine updated XUnit in our solution and merged it into our main branch. When I pulled the new code locally and tried to restore the NuGet packages...