The different levels of testing are well known: A bug found by the customer is extremely expensive, a bug found in acceptance testing somewhat less. At the end of the chain, usually, unit tests are listed as the quickest and cheapest mechanism to catch quality problems early. I would argue that this hierarchy still lacks... Continue Reading →
Escalating Java Records
Records are part of the Java language since version 14. They are a useful feature for types that primarily capture data and avoid some of the boilerplate that Java is famous for. While many traditional class hierarchies could be translated to records, I found the discussion around which of them should be adapted to that... Continue Reading →
Availability vs Latency: A False Dichotomy
When designing distributed systems, we sometimes think of latency and availability as two technical dimensions to balance out in our designs. I would like to argue that a more useful perspective would be to see them as two sides of the same coin. When discussing the design of a system, we typically need to carefully... Continue Reading →
Clean Code: Simple and Easy
If we had to write a list of typical skills we expect of Software Engineers, “writing clean code” would probably be on it. However, the trouble with clean code is that it is hardly an objective measure. I don't think I've ever worked in a team where everyone had the same understanding of what it... Continue Reading →
A Solution to the Diamond Dependency Problem
In this article, I want to explore a strategy of dependency management that enables transitive dependencies to evolve independently and to disentangle the gnarly problem of conflicting transitive dependencies. Dependency hell is a real place. The times I am struggling trying to find a matching set of dependencies are moments in which I ask myself... Continue Reading →
Cutting the System
Cutting up large systems into smaller components is one typical task of software architecture. Many modern architectures follow a (micro-) service pattern which is one particular family of strategies to decompose a larger system into smaller parts. It would be short-sighted to apply any such method without consideration of its respective strengths and weaknesses and... Continue Reading →
The Bright Future Of Property Based Testing
Automated tests are strange creatures, they are code that validates code, written by fallible beings. The messier the system under test, the messier the code required to test it. I have grown increasingly fond of property-based testing as a better technique of automated verification of software and in the following paragraphs I am going to... Continue Reading →
“What does this thing do?”
There are many principles and rules out there that offer guidance about good code design. I am generally skeptical about dogmas. Nevertheless, sometimes when I am deep in the trenches I do find it useful to have a rule of thumb to apply to quickly assess whether I'm on the right track. Such a rule... Continue Reading →
Let’s Decentralize Continuous Integration Systems
Something that has always bugged me about the current direction of the Continous Integration (CI) ecosystem is the reliance on centralized tools. The promise is to make the configuration simple. I would claim that even simple build scripts quickly fall victim to the old bash-script death spiral. There must be a better way! Certainly, there... Continue Reading →
Every Simple Language Will Eventually End Up Turing Complete
It is a cliche of the software world that change is the only constant. Nevertheless, despite the constant mushrooming of new technologies, it seems that some principles stay surprisingly constant, at least during the period that I can remember. In this article, I would like to propose one such constant by postulating the theorem of... Continue Reading →