Is software engineering solved? Depends who you ask. People selling LLMs proclaim that programming, software architecture, everything has been solved. (Apart from making their company profitable.) Not everyone agrees, of course. In this post I want to explore what the folktales we grew up on can teach us about AI-assisted software engineering. Kent Beck calls LLMs genies . Only a genius like Kent…
I was recently asked this question on LinkedIn . My short answer: yes. But the more interesting question is why , and why AI might make them more relevant, not less. Reframing the Question Some say SOLID principles are outdated. They’re not. SOLID principles are guidelines for designing modular systems. They address forces that exist in software regardless of who (or what) produces the code.…
“I can’t rely on LLMs because they’re not deterministic. How can I be sure what I’ll get?” — I bet you’ve thought that yourself. I did for sure. It’s a fair point. LLMs can be unpredictable: the same input can produce different outputs. But here’s the thing: neither are you deterministic, nor am I. A cup of coffee can dramatically improve our…
Vibe coding, or as some prefer to call it, “hands-off” software engineering, is having its moment. AI agents write code, implement features, and even spin up entire projects from a prompt. The results are impressive for demos. For production systems, not so much. The knee-jerk reaction is to blame the models. That was my reaction too. But the problem isn’t the models. It’s…
“Words should be weighed, not counted.” — A Yiddish Saying Static code analysis tools count dependencies, calculate ratios, and assign neat scores. Yet in my experience, chasing those metrics never really made the design more modular. It’s so easy to game the scores without any improvement to the design itself. Let’s see why, and what you can do instead. The Counting…
Every other post on my feed celebrates how AI lets us write code faster: whole apps built in a matter of a few hours, 99% AI-generated codebases, hundred-fold productivity gains, and on and on. But does writing code faster actually make us more productive? A Quick Detour Through a Factory The Theory of Constraints says that every system’s throughput is limited by a single constraint: its…
Lately I’ve been spending more and more time researching AI models and their effects on software engineering and architecture, so it’s time to share my findings. First, let me explain what I mean by “complicated.” I’m a huge fan of the Cynefin framework. If you are not familiar with it, here is the gist. Cynefin Say you need to decide on something. For example,…
This weekend, I have a rare opportunity to write about two things I care deeply about: Domain-Driven Design and Formula 1. If you’re not into Formula 1, don’t worry—I’ll give a brief heads-up into the domain and the ubiquitous language of the relevant bounded context. The Crash This race weekend in the beautiful Japan started with a scare. During a pre-race practice, Jack Doohan, a rookie driver…
One of the most common pieces of feedback I received about Balancing Coupling in Software Design was that readers wanted a resource they could easily share with colleagues—a quick way to introduce the balanced coupling model and make discussions about it more accessible. To meet that need, I created coupling.dev , a website that distills the core concepts of balanced coupling and related models…
My news feed these days: “Take a look at the app I built with zero coding skills!” “50% of our code is now written by AI!” “Engineering hiring freeze: AI is the future!” Alright then. Time for me to jump on the vibe coding bandwagon and share an opinion that some may categorize as a hot take. The notion of modularity was introduced to software engineering way back in the late 1960s. Today — many…
My previous post in this series discussed the reliability issues many messaging-based systems suffer from and how to address them by implementing the outbox pattern. This post switches the focus from publishing to processing messages published by other components of the system. As before, I will start by defining the problem we have to tackle. The Problem Let’s revisit the outbox pattern once…
In my previous post in the series , I discussed the basic building blocks for implementing event-driven architecture (EDA) using AWS managed services. This post is about the advanced basics. It’s advanced because, based on my consulting experience, very few companies apply the practices I want to discuss. However, I still consider this as basics because these practices are not optional but…
When you couple two components, they need to share some form of knowledge: public interfaces, functional behavior, implementation details, or other types of information. Let’s call it the integration strength. The more knowledge is shared, the stronger the integration. The stronger the integration, the more both components will have to change together. Therefore, you should always look to minimize…
Frist of all, today is the 🐒 book’s birthday! 🎉 Exactly three years ago, Learning Domain-Driven Design was published! And what a birthday present the monkey received: today marks the official release of Balancing Coupling in Software Design ! The new book is available in print and electronic formats on Amazon , InformIT , and other major book stores 🎉
The abundance of services provided by AWS often makes it possible to implement the same functionality in different ways. In the case of messaging systems, AWS offers services such as Simple Notification Service (SNS), Simple Queue Service (SQS), EventBridge, Kinesis, and Managed Streaming for Apache Kafka (MSK). It may seem that at least a subset of these services duplicates the same…
The microservices honeymoon period is over. Uber is refactoring thousands of microservices into a more manageable solution [1]; Kelsey Hightower is predicting monoliths are the future [2]; and even Sam Newman is declaring that microservices should never be the default choice, but rather a last resort [3]. What’s going on here? Why have so many projects become unmaintainable, despite…
Ladies and Gentlemen, lo and behold a new consistency model - “Optimistic Consistency”. Implementation of this pattern is quite simple: commit as many transactions as you want, against as many storage mechanisms as you need. That’s all. Let’s see an example. Example Say as the result of some user’s operation the system has to: Modify data in MongoDB Publish some events to Kafka Update search model…
There is a pet peeve of mine, that I’m encountering way too often: the condition I call Silverbulletitis. This virus spreads among developers on many levels — juniors, seniors, and even architects. In this post I’d like talk about why this condition is dangerous, and how it can be treated. Symptoms All too often you can hear statements that some tool or technique is bad, but another one is the…
So a few days ago I’ve decided to move to another cellular carrier. I pushed the new sim-card in, and got greeted with “Could not activate cellular data network”. First instinct was to install the new carrier’s APN configuration profile, but this resulted in another bummer: “Only one APN configuration can be installed at a time”. Ok, so I have to delete the previous carrier’s profile. Settings ->…
Microservices have taken our industry by storm. Teams around the world have ditched their clumsy monoliths in favor of chasing the dream of loosely coupled, manageable, and independently deployable microservices. Unfortunately, many of them ended up worse off than they were before - in the realm of distributed monoliths. Why? “If I had an hour to solve a problem I’d spend 55 minutes thinking…
I have quite a few friends in the DDD community. Fortunately, or not, we always tend to disagree on the definitions of such basic terms as Domains and Subdomains. In this post, I want to think aloud and outline my thoughts on the subject. Disclaimer As I just said, some of the things I’m about to write are my opinion only. Many of you might disagree with some of them. Hey – the last time we spoke…
I’ve always considered Domain-Driven Design’s Bounded Context as a guideline for defining the boundaries of Microservices. I was wrong. Not only is this heuristic flawed, but Bounded Contexts are the exact opposite of Microservices! To explain this point of view, I’ll start with a quick refresh of what Bounded Contexts are; then I’ll discuss the relationship between Bounded Contexts and…
If you’re using Apache NiFi to move data around, you might stumble upon Unicode characters turning into question marks. For example, the ExecuteSQL processor does that. To fix this you have to set JVM’s default encoding to UTF-8.
The CQRS pattern can do wonders: it can maximize scalability, performance, security, and even “beat” the CAP theorem . Nonetheless, CQRS has acquired a controversial name because of the complexity it introduces. For instance, in his article on CQRS , Martin Fowler argues that the pattern should be applied sparingly and even cautiously: “… for most systems CQRS adds risky complexity” “… you should…
In my previous rant post on TDD I’ve argued that the majority of the problems many experience doing TDD are caused by testing in too narrow scopes - using classes as units of testability, instead of functional use cases. However, widening the scope of the test too much is just another extreme. So how one finds the sweet spot? In this post I’d like to share the heuristic that I use.
Let’s do a little experiment: try to explain the gist of Domain-Driven Design to someone who has no clue about it. This, especially doing it succinctly, is not easy. Heck, I struggle with it myself. Bounded contexts, entities, domain events, value objects, domains, aggregates, repositories… where do you even start? To find the order in the apparent chaos, I want to analyze the DDD methodology from…
One simple question can shed a lot of light on one’s competency in a given field: “On a scale of 1 to 10, please rate your knowledge of [enter-name-of-the-field-here]“. One can assume that the higher the grade, the better. But that’s not the case at all. Why? Science — that’s why. Enter the Dunning-Kruger effect.
Last month, I had the pleasure of attending the Domain Driven Design Europe conference in Brussels. As I’ve tweeted before, this was the best conference I’ve ever attended. In this post, I’d like to sum the things I’ve learned at the conference. It’s Not (Only) About Sessions It was the first time I’ve attended a conference alone. Honestly, I was afraid that my introverted side would take…
Test Driven Development has been praised by our industry’s aficionados for a long time. However, lately there have been many harsh words said towards TDD, as it’s being blamed for causing bad software design and not keeping many of its promises. This trend culminated in David Heinemeierhansson’s post “TDD is dead. Long live testing” . How is it possible, that the same technique, which is so…
Having spent the majority of my career in the Microsoft stack, lately I’ve decided to step out of my comfort zone and to dive into the world of open source software. The project I’m currently working on at my day job is a RESTful service. The service will be running on a commodity hardware, that should be able to scale horizontally as needed. To do the job I’ve decided to use…
Last week I’ve needed a utility to convert a file containing json data to csv. I found many online solutions, but for some weird reason they didn’t support nested objects and arrays. So I wrote one, this time in python.
If you’ll ever try to generate JSON file using Sql Server’s Management Studio, probably there’ll be lots of pain in your future. If you wanna save the pain, you can use SQL2JSON, an open source project I started last week. The idea was born out of a need to generate a huge JSON file containing data from MSSQL database. After seeing our DBA struggling with formatting, escaping…
Today I wrote a small script to find and delete duplicate files. To do this task I needed to iterate over files in a specific folder, and calculate md5 checksum for each file: for folder, subs, files in os.walk(path): for filename in files: file_path = os.path.join(folder, filename) with open(file_path, 'rb') as fh: ... If the source folder contains a file or a folder with unicode characters in…
Tight coupling is a known source for inflexible and hard to test code. In this post I want to talk about a rather unexpected source of tight coupling - configuration files. Configuration files are external dependencies. As other external dependencies, its infrastructure may change in the future, and it should be easily mocked for unit testing. Modern software frameworks provide means for easy…
On the project I’m working on I’ve had a requirement to store and read files from the file system. Alse the files had to be accessible from the web. Having a gut feeling that the infrastructure may change as the business will grow, I decided to hide operations on the file system behind an interface: public interface IFilesStorage { string StoreFile(Stream stream, string fileName); Stream…
Choosing the right pattern for implementing dependency injection is an important task and can affect your class’s usability and functionality. In this post I’ll overview 3 patterns of implementing dependency injection - constructor injection, property injection, builder (Joshua Bloch’s pattern, not GoF pattern). For demonstration purposes we will work with a class called TextTranslator, that…
The general rule says that if you created an object, then it is your responsibility to dispose it. Things get a bit tricky when objects are created by a dependency injection container. The responsibility of containers is to construct objects and inject the dependencies they need. An error I’ve seen people doing again and again is to dispose objects that were injected into an object via constructor…
Vladik (Vlad) Khononov is a software engineer with over 15 years of industry experience, during which he has worked for companies large and small in roles ranging from webmaster to chief architect. Vlad is a long-time proponent of domain-driven design and evolutionary architecture and currently helps companies make sense of their business domains, untangle monoliths, and tackle complex…
Balancing Coupling in Software Design (Pearson, 2024) Learn How Coupling Impacts Every Software Design Decision You Make–and How to Control It “Coupling is one of those words that is used a lot, but little understood. Vlad propels us from simplistic slogans like ‘always decouple components’ to a nuanced discussion of coupling in the context of complexity and software…
During the last few years I spoke at leading software engineering conferences, e.g. O’Reilly Software Architecture, NDC, DDD Europe, and more. My topics include Domain-Driven Design, microservices, TDD, modular design, evolutionary architecture, and software arechitecture in general. Feel free to reach out if you’d like me to speak at your conference or on-site event. Past Events…
Consulting My core areas of expertise include domain-driven design, microservices, event sourcing, event storming, CQRS, and distributed systems. I can help you to: Develop a strategy for incremental refactoring of monolithic codebases into modular microservice-based systems Build an architectural strategy for a startup company Document and manage software architecture Align software architecture…
For any type of enquiry, you can contact me via either of the methods below: Email: vlad at khononov.com Twitter: @vladikk Github: vladikk Linkedin: Vlad Khononov
Privacy Policy for vladikk.com Last Updated: 2024/09/30 Welcome to vladikk.com (the “Blog”). This privacy policy explains how Vlad Khononov (“I”, “me”, or “my”) collects, uses, and protects your personal information when you visit and interact with the Blog. Information I Collect I collect personal information in the following ways: Directly from You: If you voluntarily subscribe to my newsletter…
A More Beautiful Question: The Power of Inquiry to Spark Breakthrough Ideas The Goal: A Process of Ongoing ImprovementBeyond the Goal: Eliyahu Goldratt Speaks on the Theory of Constraints (Your Coach In A Box)The Choice, Revised EditionDomain-Driven Design: Tackling Complexity in the Heart of SoftwareImplementing Domain-Driven DesignScrum: The Art of Doing Twice the Work in Half the TimeFlow:…
Last Updated: 2024/09/30 Welcome to vladikk.com (the “Blog”). By accessing or using this Blog, you agree to comply with and be bound by these Terms of Use. If you do not agree to these terms, please do not use the Blog. Acceptance of Terms By accessing the Blog, you confirm that you are legally able to accept these Terms of Use and that you agree to follow them. These terms apply to all visitors…