<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Rants on Software Design</title>
    <link>https://vladikk.com/</link>
    <description>Recent content on Rants on Software Design</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>vladik@khononov.com (Vlad Khononov)</managingEditor>
    <webMaster>vladik@khononov.com (Vlad Khononov)</webMaster>
    <lastBuildDate>Thu, 26 Feb 2026 00:00:00 +0000</lastBuildDate>
    
	<atom:link href="https://vladikk.com/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Coupling Should Be Weighed, Not Counted</title>
      <link>https://vladikk.com/2026/02/26/coupling-weighed/</link>
      <pubDate>Thu, 26 Feb 2026 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2026/02/26/coupling-weighed/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/weighed-not-counted.png&#34; alt=&#34;A balance scale where a single heavy weight outweighs many smaller pieces — illustrating that one heavy dependency can matter more than many lightweight ones.&#34; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Words should be weighed, not counted.&amp;rdquo; — A Yiddish Saying&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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&amp;rsquo;s so easy to game the scores without any improvement to the design itself. Let&amp;rsquo;s see why, and what you can do instead.&lt;/p&gt;

&lt;h2 id=&#34;the-counting-approach&#34;&gt;The Counting Approach&lt;/h2&gt;

&lt;p&gt;Most static analysis tools evaluate coupling by counting dependencies. Afferent coupling (Ca) counts how many components depend on yours. Efferent coupling (Ce) counts how many components yours depends on. A popular instability metric combines them into a neat formula:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;I = Ce / (Ce + Ca)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The higher the ratio of outgoing to total dependencies, the more &amp;ldquo;unstable&amp;rdquo; a component is considered. Simple. Automatable. And deeply misleading.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>AI Doesn&#39;t Fix Your Real Bottleneck</title>
      <link>https://vladikk.com/2026/02/23/ai-toc-bc/</link>
      <pubDate>Mon, 23 Feb 2026 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2026/02/23/ai-toc-bc/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/ai-toc.png&#34; alt=&#34;An assembly line where an AI robot speeds up code production, creating a massive pile of blocks in front of an overwhelmed human operator with a warning alarm — illustrating how accelerating code generation creates a bottleneck at human comprehension.&#34; /&gt;&lt;/p&gt;

&lt;p&gt;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?&lt;/p&gt;

&lt;h2 id=&#34;a-quick-detour-through-a-factory&#34;&gt;A Quick Detour Through a Factory&lt;/h2&gt;

&lt;p&gt;The Theory of Constraints says that every system&amp;rsquo;s throughput is limited by a single constraint: its bottleneck. What makes a system more effective? Improving the bottleneck. What makes a system less efficient? Improving anything else.&lt;/p&gt;

&lt;p&gt;I know, that second part is counterintuitive. Here&amp;rsquo;s the thing: if you speed up a non-bottleneck, you don&amp;rsquo;t improve the system; you produce more work-in-progress that piles up in front of the bottleneck! More inventory. More cost. More waste. The system becomes more expensive to operate, not more productive.&lt;/p&gt;

&lt;p&gt;This is a well-established principle in manufacturing, and software manufacturing is no exception.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>With AI, everything is so complicated... and this is great news!</title>
      <link>https://vladikk.com/2025/05/26/with-ai-everything-is-complicated/</link>
      <pubDate>Mon, 26 May 2025 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2025/05/26/with-ai-everything-is-complicated/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/ai-everything-is-complicated.png&#34; alt=&#34;With AI, everything is so complicated... and this is great news!&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Lately I&amp;rsquo;ve been spending more and more time researching AI models and their effects on software engineering and architecture, so it&amp;rsquo;s time to share my findings.&lt;/p&gt;

&lt;p&gt;First, let me explain what I mean by &amp;ldquo;complicated.&amp;rdquo; I&amp;rsquo;m a huge fan of the Cynefin framework. If you are not familiar with it, here is the gist.&lt;/p&gt;

&lt;h2 id=&#34;cynefin&#34;&gt;Cynefin&lt;/h2&gt;

&lt;p&gt;Say you need to decide on something. For example, let&amp;rsquo;s assume you need to change the behavior of a software application and are contemplating how to do it.&lt;/p&gt;

&lt;p&gt;Cynefin is a tool for guiding the decision-making process in different kinds of
situations.  It says that first you need to understand what kind of situation you are in, and once you do, picking the optimal course of action is much easier. For that, the framework identifies four basic situations—domains:&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>F1 &#43; DDD: All Models are Wrong, Some are Dangerous</title>
      <link>https://vladikk.com/2025/04/05/f1-ddd/</link>
      <pubDate>Sat, 05 Apr 2025 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2025/04/05/f1-ddd/</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;h2 id=&#34;the-crash&#34;&gt;The Crash&lt;/h2&gt;

&lt;p&gt;This race weekend in the beautiful Japan started with a scare. During a pre-race practice, Jack Doohan, a rookie driver from the Alpine team, suddenly spun out of control in the highest-speed section of the track and hit a wall (&lt;a href=&#34;https://www.youtube.com/watch?v=49H4qtfUv24&#34;&gt;video&lt;/a&gt;). He was going over 320 kilometers per hour (200 miles per hour) at the time. Thanks to the marvels of modern race car engineering, Jack walked away unharmed—not even a concussion. But why did it happen in the first place?&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/f1-crash.png&#34; alt=&#34;Jack Doohan&#39;s crash Practice 2&#34; /&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Just Launched: coupling.dev</title>
      <link>https://vladikk.com/2025/04/03/coupling-dev/</link>
      <pubDate>Thu, 03 Apr 2025 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2025/04/03/coupling-dev/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/coupling-dev-t.png&#34; alt=&#34;coupling.dev&#34; /&gt;&lt;/p&gt;

&lt;p&gt;One of the most common pieces of feedback I received about &lt;a href=&#34;https://amzn.to/4irApMt&#34;&gt;&lt;em&gt;Balancing Coupling in Software Design&lt;/em&gt;&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;To meet that need, I created &lt;a href=&#34;https://coupling.dev&#34;&gt;coupling.dev&lt;/a&gt;, a website that distills the core concepts of balanced coupling and related models into concise, approachable posts. It also serves as a hub for other learning resources, including conference talks and podcast appearances, helping teams streamline adoption and deepen their understanding together.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>The Golden Age of Modularity</title>
      <link>https://vladikk.com/2025/03/30/golden-age-of-modularity/</link>
      <pubDate>Sat, 29 Mar 2025 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2025/03/30/golden-age-of-modularity/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/ai-boundaries.png&#34; alt=&#34;The Golden Age of Modularity: Why Modern Architecture—and AI—Depend on Better Boundaries&#34; /&gt;&lt;/p&gt;

&lt;p&gt;My news feed these days:&lt;br /&gt;
“Take a look at the app I built with zero coding skills!”&lt;br /&gt;
“50% of our code is now written by AI!”&lt;br /&gt;
“Engineering hiring freeze: AI is the future!”&lt;/p&gt;

&lt;p&gt;Alright then. Time for me to jump on the vibe coding bandwagon and share an opinion that some may categorize as a hot take.&lt;/p&gt;

&lt;p&gt;The notion of modularity was introduced to software engineering way back in the late 1960s. Today — many decades later — we&amp;rsquo;re entering the golden age of modularity. To understand why, let’s first define what modularity actually is.&lt;/p&gt;

&lt;h2 id=&#34;modularity&#34;&gt;Modularity&lt;/h2&gt;

&lt;p&gt;There are many ways to define modularity — from designing software systems as interchangeable LEGO blocks to chasing the holy grail of reusable “building blocks” meant to be plugged into anything and everything. I prefer a more practical perspective. To me, a modular design satisfies two key criteria:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When you need to change the codebase—whether to adjust existing functionality or introduce a new one—it’s crystal clear what parts of the system need to be touched. Ideally, the number of affected components should be as small as possible. Preferably, just one.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;When you introduce a change to a modular system, you know exactly what the effect of that change will be. You can predict the system’s behavior.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    
    <item>
      <title>Event-Driven Architecture on AWS, Part III: The Hard Basics</title>
      <link>https://vladikk.com/2024/10/13/aws-eda-iii/</link>
      <pubDate>Sun, 13 Oct 2024 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2024/10/13/aws-eda-iii/</guid>
      <description>&lt;p&gt;My &lt;a href=&#34;https://vladikk.com/2024/10/12/aws-eda-ii/&#34;&gt;previous post&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;As before, I will start by defining the problem we have to tackle.&lt;/p&gt;

&lt;h2 id=&#34;the-problem&#34;&gt;The Problem&lt;/h2&gt;

&lt;p&gt;Let’s revisit the outbox pattern once more. It addresses the common problem of publishing messages after the underlying business transaction has already been committed: the events might not get published at all. By implementing the pattern, you ensure that all the events will be published—&lt;em&gt;at least once&lt;/em&gt;. Let me explain the last part.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/aws-eda-2/fig-1.png&#34; alt=&#34;The outbox pattern&#34; /&gt;
&lt;em&gt;Figure 1: The outbox pattern&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Event-Driven Architecture on AWS, Part II: The Advanced Basics</title>
      <link>https://vladikk.com/2024/10/12/aws-eda-ii/</link>
      <pubDate>Sat, 12 Oct 2024 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2024/10/12/aws-eda-ii/</guid>
      <description>&lt;p&gt;In my &lt;a href=&#34;https://vladikk.com/2024/09/28/aws-eda/&#34;&gt;previous post in the series&lt;/a&gt;, I discussed the basic building blocks for implementing event-driven architecture (EDA) using AWS managed services. This post is about the &lt;em&gt;advanced&lt;/em&gt; 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 essential for implementing reliable messaging-based systems.&lt;/p&gt;

&lt;p&gt;Although the examples in this post use AWS services, the material applies to any system, regardless of the infrastructure it runs on. The implementation might differ, but the underlying principles remain the same.&lt;/p&gt;

&lt;p&gt;Since this post is about a pattern—and patterns, by definition, are repeatable solutions to commonly occurring problems—I want to begin by discussing a commonly overlooked problem in EDA-based systems.&lt;/p&gt;

&lt;h2 id=&#34;the-problem&#34;&gt;The Problem&lt;/h2&gt;

&lt;p&gt;In the previous post, I suggested using AWS SNS for publishing messages in an event-driven system. Here’s a common example of how such publishing is carried out:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;...

sns.publish(
    TopicArn=users_topic_arn,
    Message=json.dumps({
        &#39;event_type&#39;: &#39;user_registered&#39;,
        &#39;event_id&#39;: str(uuid.uuid4()),
        &#39;user_id&#39;: &#39;USER12345&#39;,
        &#39;name&#39;: &#39;John Doe&#39;,
        &#39;email&#39;: &#39;john.doe@example.com&#39;,
        &#39;source&#39;: &#39;mobile_app&#39;,
        &#39;registration_date&#39;: &#39;2024-10-11T20:01:00Z&#39;
    })
)

...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the above example, an event of type &lt;code&gt;user_registered&lt;/code&gt; is published to an SNS topic. But did that event come from thin air? Is that all services do, just publish messages? Of course not. The event is part of a larger business process that typically involves updating some state in an operational database before notifying external components about it. A more accurate representation of this process would look like this:&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>The Essence of Coupling and Cohesion in Under 500 Words</title>
      <link>https://vladikk.com/2024/10/09/coupling-and-cohesion/</link>
      <pubDate>Wed, 09 Oct 2024 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2024/10/09/coupling-and-cohesion/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/strength-and-distance.png&#34; alt=&#34;Integration Strength and Distance&#34; /&gt;&lt;/p&gt;

&lt;p&gt;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 the integration strength. That said, minimizing integration strength isn’t always possible—sometimes, extensive shared knowledge is necessary. For example, when the components implement closely related business functionalities.&lt;/p&gt;

&lt;p&gt;Another important property of integrated components is the distance between them. For example, objects in a module are located closer to each other than the source code of two microservices. The greater the distance, the higher the induced cognitive load and coordination challenges, and the more effort is needed to change the integrated components simultaneously.&lt;/p&gt;

&lt;p&gt;Now let’s examine four extreme combinations of the two dimensions:&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Balancing Coupling in Software Design🎉</title>
      <link>https://vladikk.com/2024/10/08/lddd-bcisd/</link>
      <pubDate>Tue, 08 Oct 2024 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2024/10/08/lddd-bcisd/</guid>
      <description>&lt;p&gt;Frist of all, today is the 🐒 book’s birthday! 🎉&lt;/p&gt;

&lt;p&gt;Exactly three years ago, &lt;em&gt;Learning Domain-Driven Design&lt;/em&gt; was published! And what a birthday present the monkey received: today marks the official release of &lt;em&gt;Balancing Coupling in Software Design&lt;/em&gt;! The new book is available in print and electronic formats on &lt;a href=&#34;https://amzn.to/3BIIPyk&#34;&gt;Amazon&lt;/a&gt;, &lt;a href=&#34;https://click.linksynergy.com/deeplink?id=XLXvHJZS*qY&amp;amp;mid=24808&amp;amp;murl=https%3A%2F%2Fwww.informit.com%2Fstore%2Fbalancing-coupling-in-software-design-universal-design-9780137353484&#34;&gt;InformIT&lt;/a&gt;, and other major book stores 🎉&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/lddd-three-years.png&#34; alt=&#34;Learning Domain-Driven Design&#39;s third anniversary&#34; /&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Event-Driven Architecture on AWS, Part I: The Basics</title>
      <link>https://vladikk.com/2024/09/28/aws-eda/</link>
      <pubDate>Sat, 28 Sep 2024 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2024/09/28/aws-eda/</guid>
      <description>&lt;p&gt;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 functionality. In this post, I want to describe my go-to architecture and explain why, in my opinion, it is the simplest, most cost-effective, and robust solution for the majority of cases.&lt;/p&gt;

&lt;h2 id=&#34;event-driven-architecture&#34;&gt;Event-Driven Architecture&lt;/h2&gt;

&lt;p&gt;Components of an event-driven system communicate by publishing and subscribing to events. The asynchronous integration offers significant non-functional advantages. For example, it decouples the integrated components’ lifecycles. To a certain degree, the system can keep functioning even in the face of unavailability of some of its services, thus also reducing the coordination overhead needed to deploy updated components, and to evolve the system.&lt;/p&gt;

&lt;p&gt;A basic event-driven integration is comprised of two parts: a component of the system can publish events describing important occurrences in its lifecycle, and it can react (subscribe) to events published by other parts of the system. Let’s see what managed services we can leverage for implementing this.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Untangling Microservices, or Balancing Complexity in Distributed Systems</title>
      <link>https://vladikk.com/2020/04/09/untangling-microservices/</link>
      <pubDate>Thu, 09 Apr 2020 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2020/04/09/untangling-microservices/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/untangling-microservices/header.png&#34; alt=&#34;Untangling Microservices, or Balancing Complexity in Distributed Systems&#34; /&gt;&lt;/p&gt;

&lt;p&gt;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].&lt;/p&gt;

&lt;p&gt;What&amp;rsquo;s going on here? Why have so many projects become unmaintainable, despite microservices’ promise of simplicity and flexibility? Or are monoliths better, after all?&lt;/p&gt;

&lt;p&gt;In this post, I want to address these questions. You will learn about common design issues that turn microservices into distributed big balls of mud – and, of course, how you can avoid them.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Anti-Pattern: Optimistic Consistency</title>
      <link>https://vladikk.com/2019/04/18/optimistic-consistency/</link>
      <pubDate>Thu, 18 Apr 2019 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2019/04/18/optimistic-consistency/</guid>
      <description>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 in Elasticsearch; and Execute an operation on some remote system  You implement this logic by executing those operations one after another.</description>
    </item>
    
    <item>
      <title>Zen of Software Engineering</title>
      <link>https://vladikk.com/2019/01/29/zen-software-engineering/</link>
      <pubDate>Tue, 29 Jan 2019 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2019/01/29/zen-software-engineering/</guid>
      <description>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 greatest thing since sliced bread.</description>
    </item>
    
    <item>
      <title>IOS 11: Fixing APN Configuration Issues</title>
      <link>https://vladikk.com/2018/03/28/ios-apn-bug/</link>
      <pubDate>Wed, 28 Mar 2018 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2018/03/28/ios-apn-bug/</guid>
      <description>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 -&amp;gt; General -&amp;gt; Profiles …and there weren’t any profiles: “No profiles are currently installed”.</description>
    </item>
    
    <item>
      <title>Tackling Complexity in Microservices</title>
      <link>https://vladikk.com/2018/02/28/microservices/</link>
      <pubDate>Wed, 28 Feb 2018 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2018/02/28/microservices/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/microservices/title-img.jpg&#34; alt=&#34;Tackling Complexity in Microservices&#34; /&gt;&lt;/p&gt;

&lt;p&gt;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?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If I had an hour to solve a problem I&amp;rsquo;d spend 55 minutes thinking about  the problem and 5 minutes thinking about solutions” - Albert Einstein&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my opinion, this quote is the key to solving most of the issues we have when designing microservices-based systems. We rush into solutions without ensuring we know what exactly a microservice is. In this post, I’d like to take a stab at answering this question.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Revisiting the Basics of Domain-Driven Design</title>
      <link>https://vladikk.com/2018/01/26/revisiting-the-basics-of-ddd/</link>
      <pubDate>Fri, 26 Jan 2018 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2018/01/26/revisiting-the-basics-of-ddd/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/domains/title-img.jpg&#34; alt=&#34;Revisiting the Basics of Domain-Driven Design&#34; /&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h2&gt;

&lt;p&gt;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 about it, Eric and Vaughn were not fans of my theory. But, nevertheless, it is based on my 7-year long DDD journey at our company, and it works for me. I believe it might work for you as well.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Bounded Contexts are NOT Microservices</title>
      <link>https://vladikk.com/2018/01/21/bounded-contexts-vs-microservices/</link>
      <pubDate>Sun, 21 Jan 2018 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2018/01/21/bounded-contexts-vs-microservices/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/bc-ms/rebel-scum.jpg&#34; alt=&#34;Rebel scum&#34; /&gt;&lt;/p&gt;

&lt;p&gt;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 Microservices.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Apache NiFi: Enabling Unicode Support</title>
      <link>https://vladikk.com/2017/03/30/nifi-unicode/</link>
      <pubDate>Thu, 30 Mar 2017 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2017/03/30/nifi-unicode/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;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&amp;rsquo;s default encoding to UTF-8.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Tackling Complexity in CQRS</title>
      <link>https://vladikk.com/2017/03/20/tackling-complexity-in-cqrs/</link>
      <pubDate>Mon, 20 Mar 2017 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2017/03/20/tackling-complexity-in-cqrs/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/cqrs/title-img.jpg&#34; alt=&#34;Tackling Complexity in CQRS&#34; /&gt;&lt;/p&gt;

&lt;p&gt;The CQRS pattern can do wonders: it can maximize scalability, performance, security, and even &lt;a href=&#34;http://codebetter.com/gregyoung/2010/02/20/cqrs-and-cap-theorem/&#34;&gt;“beat” the CAP theorem&lt;/a&gt;. Nonetheless, CQRS has acquired a controversial name because of the complexity it introduces. For instance, &lt;a href=&#34;https://martinfowler.com/bliki/CQRS.html&#34;&gt;in his article on CQRS&lt;/a&gt;, Martin Fowler argues that the pattern should be applied sparingly and even cautiously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“… for most systems CQRS adds risky complexity”&lt;/li&gt;
&lt;li&gt;“… you should be very cautious about using CQRS”&lt;/li&gt;
&lt;li&gt;“So while CQRS is a pattern that&amp;rsquo;s good to have in the toolbox, beware that it is difficult to use well and you can easily chop off important bits if you mishandle it.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From my point of view, the CQRS-induced complexity is largely accidental, and thus can be avoided. To illustrate my point, I want to discuss the goal of CQRS, and then analyze 3 common sources of accidental complexity in CQRS-based systems.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Finding Proper Scopes for Unit Tests</title>
      <link>https://vladikk.com/2016/06/29/test-scopes/</link>
      <pubDate>Wed, 29 Jun 2016 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2016/06/29/test-scopes/</guid>
      <description>&lt;p&gt;In my previous &lt;strike&gt;rant&lt;/strike&gt; &lt;a href=&#34;http://vladikk.com/2016/01/22/tdd-what-went-wrong/&#34;&gt;post on TDD&lt;/a&gt; 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.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Tackling Complexity in the Heart of DDD</title>
      <link>https://vladikk.com/2016/04/05/tackling-complexity-ddd/</link>
      <pubDate>Tue, 05 Apr 2016 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2016/04/05/tackling-complexity-ddd/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/ddd/title-img.jpg&#34; alt=&#34;Tackling Complexity in the Heart of Domain-Driven Design&#34; /&gt;&lt;/p&gt;

&lt;p&gt;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?&lt;/p&gt;

&lt;p&gt;To find the order in the apparent chaos, I want to analyze the DDD methodology from a rather unusual perspective — by applying Domain-Driven Design to Domain-Driven Design itself. After all, this methodology is intended to deal with complex domains, isn’t it?&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>A Quick and Dirty Hack for Interviewing Job Candidates</title>
      <link>https://vladikk.com/2016/03/05/interviewing/</link>
      <pubDate>Sat, 05 Mar 2016 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2016/03/05/interviewing/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://vladikk.com/images/interviewing/title-img.jpg&#34; alt=&#34;A Quick and Dirty Hack for Interviewing Job Candidates&#34; /&gt;&lt;/p&gt;

&lt;p&gt;One simple question can shed a lot of light on one’s competency in a given field: &amp;ldquo;On a scale of 1 to 10, please rate your knowledge of [enter-name-of-the-field-here]&amp;ldquo;.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>DDDEU 2016 Impressions</title>
      <link>https://vladikk.com/2016/02/12/dddeu-2016/</link>
      <pubDate>Fri, 12 Feb 2016 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2016/02/12/dddeu-2016/</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;h2 id=&#34;it-s-not-only-about-sessions&#34;&gt;It&amp;rsquo;s Not (Only) About Sessions&lt;/h2&gt;

&lt;p&gt;It was the first time I’ve attended a conference alone. Honestly, I was afraid that my introverted side would take over, and I’d master wallflower imitation techniques between sessions. Fortunately, it didn’t happen. I felt at home the moment I left the hotel for the conference. From that moment on, and up until the very last moments of the conference, I met a lot of like-minded people from all over the world - Belgium, Denmark, Germany, Austria, UK, Poland, Italy, France, USA, Finland, Switzerland, Netherlands, Romania, Bulgaria, and even from Israel.&lt;/p&gt;

&lt;p&gt;For me, the social part, alone, was worth the trip. And don’t get me wrong, the sessions were great, but the ability to meet new friends, share experiences and ideas, and get fresh perspectives, was priceless.
And I’m yet to mention discussing Star Wars with Eric Evans, discovering that Vaughn Vernon knows Israel better than I do, catching up with Greg Young, and last but not least, drinking beer with Yves Reynhout — it is unbelievable how much I learned from Yves that evening.&lt;/p&gt;

&lt;p&gt;Lesson learned: Go to conferences alone and meet new people.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>TDD: What Went Wrong…Or Did It?</title>
      <link>https://vladikk.com/2016/01/22/tdd-what-went-wrong/</link>
      <pubDate>Fri, 22 Jan 2016 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2016/01/22/tdd-what-went-wrong/</guid>
      <description>&lt;p&gt;Test Driven Development has been praised by our industry&amp;rsquo;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 &lt;a href=&#34;http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html&#34;&gt;“TDD is dead. Long live testing”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;How is it possible, that the same technique, which is so advantageous to so many developers, is so disastrous to others?
In this post I want to talk about 3 misconceptions that might explain this phenomenon.&lt;/p&gt;

&lt;p&gt;Let&amp;rsquo;s start with the subtlest and most destructive one.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Serving Flask with Nginx</title>
      <link>https://vladikk.com/2013/09/12/serving-flask-with-nginx-on-ubuntu/</link>
      <pubDate>Thu, 12 Sep 2013 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2013/09/12/serving-flask-with-nginx-on-ubuntu/</guid>
      <description>&lt;p&gt;Having spent the majority of my career in the Microsoft stack, lately I&amp;rsquo;ve decided to step out of my comfort zone and to dive into the world of open source software. The project I&amp;rsquo;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&amp;rsquo;ve decided to use Flask and Nginx. Flask is a lightweight Python web framework, and nginx is a highly stable web server, that works great on cheap hardware.&lt;/p&gt;

&lt;p&gt;In this post I will guide you through the process of installing and configuring nginx server to host Flask based applications. The OS I&amp;rsquo;ll be using is Ubuntu 13.04.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>JSON2CSV</title>
      <link>https://vladikk.com/2013/06/11/json2csv/</link>
      <pubDate>Tue, 11 Jun 2013 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2013/06/11/json2csv/</guid>
      <description>&lt;p&gt;Last week I&amp;rsquo;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&amp;rsquo;t support nested objects and arrays. So I wrote one, this time in python.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Introducing SQL2JSON</title>
      <link>https://vladikk.com/2013/06/09/sql2json/</link>
      <pubDate>Sun, 09 Jun 2013 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2013/06/09/sql2json/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ll ever try to generate JSON file using Sql Server&amp;rsquo;s Management Studio, probably there&amp;rsquo;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.&lt;/p&gt;

&lt;p&gt;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 weird characters and unicode strings, I decided to write a small utility that will do just that - execute a sql query and capture its results as a json file.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Unicode file names in Python 2.7</title>
      <link>https://vladikk.com/2013/06/01/unicode-file-names-in-python/</link>
      <pubDate>Sat, 01 Jun 2013 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2013/06/01/unicode-file-names-in-python/</guid>
      <description>&lt;p&gt;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:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;for folder, subs, files in os.walk(path):
    for filename in files:
        file_path = os.path.join(folder, filename)
	        with open(file_path, &#39;rb&#39;) as fh:
	        	...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If the source folder contains a file or a folder with unicode characters in it, execution of the code results in this bummer:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;IOError: [Errno 22] invalid mode (&#39;rb&#39;) or filename: &#39;files\\????????? ????? ????????.txt&#39;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Uncoupling Configuration Files</title>
      <link>https://vladikk.com/2013/05/14/uncoupling-configuration-files/</link>
      <pubDate>Tue, 14 May 2013 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2013/05/14/uncoupling-configuration-files/</guid>
      <description>&lt;p&gt;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 access to the values stored in configuration files. In the .NET framework configuration files can be accessed using the ConfigurationManager:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-xml&#34;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;configuration&amp;gt;
  &amp;lt;appSettings&amp;gt;
    &amp;lt;add key=&amp;quot;Foo&amp;quot; value=&amp;quot;1&amp;quot;/&amp;gt;
    &amp;lt;add key=&amp;quot;Bar&amp;quot; value=&amp;quot;2&amp;quot;/&amp;gt;
  &amp;lt;/appSettings&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&#34;language-csharp&#34;&gt;int foo = int.Parse(ConfigurationManager.AppSetttings[“Foo”]);
int bar = int.Parse(ConfigurationManager.AppSettings[“Bar”]);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ConfigurationManager makes it trivial to access data in the config file, however in most cases it also introduces various code smells that make the code tight coupled and hard to test. In the next sections I’ll introduce a simple class and will use it to demonstrate the code smells and violations of principles of clean object oriented design. The code will be gradually refactored to a better and cleaner solution.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Learning From Mistakes: Leaky Abstractions</title>
      <link>https://vladikk.com/2012/10/15/learning-from-mistakes-leaky-abstractions/</link>
      <pubDate>Mon, 15 Oct 2012 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2012/10/15/learning-from-mistakes-leaky-abstractions/</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-c#&#34;&gt;public interface IFilesStorage {
    string StoreFile(Stream stream, string fileName);
    Stream GetFile(string virtualPath);
    string GetFileUrl(string virtualPath);
    string GetFilePath(string virtualPath);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As it looks, if someday I’ll need to switch from the file
system to another storage mechanism, I’ll be able to do get the
job done by writing another implementation of the interface.
Right? Wrong! The requirement did come in - I’ve had to store
the files in S3. And only then I realised that IFilesStorage is
a leaky abstraction.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Dependency Injection Patterns</title>
      <link>https://vladikk.com/2012/09/10/dependency-injection-patterns/</link>
      <pubDate>Mon, 10 Sep 2012 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2012/09/10/dependency-injection-patterns/</guid>
      <description>&lt;p&gt;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 requires 3 dependencies: TextReader, TranslationService and TextWriter:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-c#&#34;&gt;public class TextTranslator
{
    protected TextReader textReader;
    protected TranslationService translationService;
    protected TextWriter textWriter;    
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The sample code will be written in C#, but the examples are applicable to Java and other object oriented languages.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Disposing Objects Created by DI Container</title>
      <link>https://vladikk.com/2012/08/23/disposing-objects-created-by-di-container/</link>
      <pubDate>Thu, 23 Aug 2012 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/2012/08/23/disposing-objects-created-by-di-container/</guid>
      <description>&lt;p&gt;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 or property injection. Consider the class “Foo” that requires an instance of class “Bar”:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-c#&#34;&gt;public class Foo : IDisposable {  
    protected Bar bar;  
    public Foo(Bar bar) {  
        this.bar = bar;  
    }  
    public void Dispose() {  
        bar.Dispose();  
    }  
}  

public class Program {  
    static void Main() {  
        var foo = container.Resolve&amp;lt;Foo&amp;gt;();  
        ...  
        foo.Dispose();  
    }  
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The problem with this approach is that the “Foo” class will know too much about the environment it runs in. At least it will think it does. An instance of “Foo” can’t and shouldn’t know who passed in the instance of “Bar”, and what he intends to do with it after the instance of “Foo” will be disposed.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>About Me</title>
      <link>https://vladikk.com/page/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/page/about/</guid>
      <description>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 architectural challenges.
Vlad maintains an active media career as a public speaker and blogger.</description>
    </item>
    
    <item>
      <title>Books</title>
      <link>https://vladikk.com/page/books/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/page/books/</guid>
      <description>Balancing Coupling in Software Design (Pearson, 2024) 
Learn How Coupling Impacts Every Software Design Decision You Make&amp;ndash;and How to Control It
&amp;ldquo;Coupling is one of those words that is used a lot, but little understood. Vlad propels us from simplistic slogans like &amp;lsquo;always decouple components&amp;rsquo; to a nuanced discussion of coupling in the context of complexity and software evolution. If you build modern software, read this book!&amp;rdquo; &amp;ndash;Gregor Hohpe, author of The Software Architect Elevator</description>
    </item>
    
    <item>
      <title>Conferences</title>
      <link>https://vladikk.com/page/speaking/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/page/speaking/</guid>
      <description>During the last few years I spoke at leading software engineering conferences, e.g. O&amp;rsquo;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&amp;rsquo;d like me to speak at your conference or on-site event.
Past Events 02/04/2020: Tackling Complexity with Domain-Driven Design Online panel discussion Language: Russian
Recording: Youtube</description>
    </item>
    
    <item>
      <title>Consulting</title>
      <link>https://vladikk.com/page/consulting/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/page/consulting/</guid>
      <description>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 with business needs Recover business logic buried in legacy codebases Migrate legacy systems to cloud infrastructure  On-Site Training I can provide training adapted to your company&amp;rsquo;s needs.</description>
    </item>
    
    <item>
      <title>Contact Me</title>
      <link>https://vladikk.com/page/contact/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/page/contact/</guid>
      <description>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  </description>
    </item>
    
    <item>
      <title>Privacy Policy</title>
      <link>https://vladikk.com/page/privacy-policy/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/page/privacy-policy/</guid>
      <description>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 or leave a comment, I may collect information such as your name and email address.</description>
    </item>
    
    <item>
      <title>Reading</title>
      <link>https://vladikk.com/page/reading/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/page/reading/</guid>
      <description>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: Living at the Peak of Your AbilitiesThe Phoenix Project: A Novel About IT, DevOps, and Helping Your Business WinSapiens: A Brief History of HumankindThe Obstacle Is the Way: The Timeless Art of Turning Trials into TriumphSimple Rules: How to Thrive in a Complex WorldGetting to Yes: Negotiating Agreement Without Giving InBorn to Run: A Hidden Tribe, Superathletes, and the Greatest Race the World Has Never SeenThe Lean Startup: How Today&amp;rsquo;s Entrepreneurs Use Continuous Innovation to Create Radically Successful BusinessesBusiness Model Generation: A Handbook for Visionaries, Game Changers, and ChallengersDrive: The Surprising Truth About What Motivates UsEnterprise Integration Patterns: Designing, Building, and Deploying Messaging SolutionsWorking Effectively with Legacy CodePatterns of Enterprise Application ArchitectureThinking, Fast and Slow</description>
    </item>
    
    <item>
      <title>Terms of Use</title>
      <link>https://vladikk.com/page/terms-of-use/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>vladik@khononov.com (Vlad Khononov)</author>
      <guid>https://vladikk.com/page/terms-of-use/</guid>
      <description>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 and users of the Blog.</description>
    </item>
    
  </channel>
</rss>