Loosely Coupled - Deep dive into coupling with Domain-Driven Design
Karol:
Good morning, good afternoon, and good evening.
Karol:
Welcome to another episode of Loosely Coupled by Bridging the Gap.
Karol:
My name is Karol Skrzymowski, I'll be your host tonight, and today's episode is sponsored by the common cold.
Karol:
So I have some nice citrus and ginger and some other herbs brewed in the pot for myself just to get through today.
Karol:
And today, well, we are having a topic that is actually very much related to the name of the stream, so we're going to talk about coupling, and in context of domain-driven design, which I think is, for our guest, is one of the few occasions when he can talk about coupling and domain-driven design at the same time, because I've seen quite a few trainings that he restrained himself very, very much.
Karol:
So, without further ado, welcome to the stream.
Karol:
Good evening, Vlad Khononov.
Vlad:
Hey, Karol, thank you so much for having me.
Karol:
Hello, hello.
Karol:
Amazing that you could join us, and we can talk about domain-driven design and coupling at the same time for a change, right?
Vlad:
Yeah, yeah.
Vlad:
Two topics I cannot shut up about, so I don't know how long this stream is going to be.
Karol:
I mean, I just been through, what was that, a month ago, through your training at O'Reilly about balancing coupling and software design.
Karol:
You really, really had to restrain yourself.
Karol:
I saw that in you.
Karol:
You were like, oh, I'm not supposed to talk about domain-driven design, but I'm going to mention domain-driven design.
Karol:
Yeah, that's true.
Karol:
Speaking about that training, before we jump into the topic, Vlad, please, please, give me an IT dad joke.
Vlad:
Oh, so you want me to embarrass myself from the get-go, right?
Vlad:
Okay.
Karol:
Let's do this.
Karol:
They were great.
Karol:
I laughed my ass off during the training, so please, please enlighten what to do when you're waiting for people to answer and chat during the live training.
Vlad:
I see.
Vlad:
Okay, so why did the programmer quit his job?
Vlad:
Why?
Vlad:
He didn't get a raise.
Vlad:
A raise?
Vlad:
A raise?
Vlad:
Yeah, smart, right?
Vlad:
That's not something I'm proud about.
Karol:
Fair enough.
Karol:
That joke's a side.
Karol:
Coupling and domain-driven design, these are the two main topics that you do, that you are about in literature, in variety trainings, talks with people.
Karol:
Why those two specifically?
Vlad:
Yeah.
Vlad:
Well, first of all, because I love domain-driven design, learning this methodology for me was truly, not exaggerating, a career-changing experience.
Vlad:
Now, eventually, that led me to coupling because during one of my DDD endeavours, I had like a complete disaster, like cosmic-level disaster of a microservices project, like something that was supposed to be this perfect microservices-based future of everything decoupled and everything that can evolve independently.
Vlad:
And it was like, buy the book, distribute monolith.
Vlad:
And the annoying thing was that I was doing what smart people were telling me to do.
Vlad:
So, whenever, when that project was completed, I said, okay, I have to understand what the hell went wrong.
Vlad:
Like, why this promise of everything uncoupled or decoupled or whatever turned out to be coupling a nightmare.
Vlad:
So, I started researching coupling and yeah, I just couldn't stop.
Vlad:
I was fascinated by this topic because it answers so many questions beyond that microservices failure.
Karol:
So, which was first, DDD or coupling?
Vlad:
DDD.
Karol:
DDD.
Karol:
Okay.
Karol:
And then, I remember you mentioning to me that it took you about five years to complete balancing coupling and software design, which was published in October 23.
Karol:
And then in the meantime, you wrote learning domain-driven design, which was published in October 21.
Karol:
So, it was like parallel, parallelly developed.
Vlad:
Yeah.
Vlad:
So, balancing coupling was published in October, end of September, I think, 24.
Vlad:
Now, I started working on both of them because, let's say, reasons, not because of something I'm proud of.
Vlad:
I did a mistake and I had to start writing two books at the same time in 2019.
Vlad:
Now, learning domain-driven design was smooth sailing for me.
Vlad:
Like, come on.
Vlad:
I did many trainings.
Vlad:
I already had that what is domain-driven design report for O'Reilly.
Vlad:
I just had to extend it.
Vlad:
And, yeah, that book was easy.
Vlad:
Now, the coupling book, it was like a real challenge.
Vlad:
It was either me or the book.
Karol:
And, of course, the writing balancing coupling and software design was basically during a very problematic geopolitical era where you are at, right?
Karol:
So, that was also quite a factor.
Vlad:
Oh, there were so many factors.
Vlad:
Like, I don't want to get into it, to be honest, because everything that could go wrong went wrong during those five years.
Vlad:
Like, everything.
Vlad:
We had COVID, by the way, 2020.
Vlad:
The whole world stopped.
Vlad:
I got stuck in a foreign country for four months.
Vlad:
I couldn't get back home.
Vlad:
Yeah.
Vlad:
So many crazy stories.
Vlad:
I can write a whole book about, you know, things going wrong during writing of balancing coupling and software design.
Vlad:
Yeah.
Vlad:
And, yeah, and eventually I missed the deadline.
Vlad:
Come on.
Karol:
What was the deadline?
Vlad:
So, the deadline, I had it back here on this wall, so now I removed it.
Vlad:
But it was, if I remember correctly, it was October 21.
Vlad:
October 21.
Vlad:
Yeah.
Karol:
Three years later.
Karol:
All right.
Karol:
Just some technical issues that we're facing.
Karol:
First technical issue.
Karol:
For some reason, comments from LinkedIn do not show up in our studio.
Karol:
So, I hope the comments from YouTube will.
Karol:
Something went wrong technically and we don't have that integration handled for some reason.
Karol:
Technology, right?
Karol:
And then the second public service announcement, because Vlad is currently experiencing a storm outside, and power tends to give out.
Karol:
So, if Vlad suddenly disappears from the stream, he'll be back in a few minutes, and then I'll be forced to say dad jokes in the meantime.
Karol:
So, for all of you to be warned that if Vlad just disappears, he'll come back.
Karol:
He'll come back.
Karol:
But it may take a minute to do so.
Karol:
I'll be monitoring LinkedIn on one of my screens, just a feed of comments anyways, just to put those questions in as we go.
Karol:
But unfortunately, for some reason, technology fails at times.
Karol:
That's what it is.
Karol:
So, as a real software engineer, you miss deadlines, you failed at a project, you decided to learn from your failures, and that's why we have learning domain-driven design, and that's why we have balancing coupling in software design as the two books.
Karol:
Both really great books, because I read both of them and enjoyed every second reading them, and they were quite influential.
Karol:
Especially for me, not knowing domain-driven design, I was way easier to digest than the blue book by Eric Evans.
Karol:
So, that was a big influence on my education, at least.
Karol:
I hope that others as well.
Karol:
I know quite a few people that read learning domain-driven design, and they really enjoyed it.
Karol:
So, now we can talk about domain-driven design in the context of coupling.
Karol:
Now, the question is, where do we begin?
Vlad:
Whenever.
Vlad:
Just pick a point, and we'll make our way through.
Karol:
Okay.
Karol:
Since I'm an integration architect, let's limit ourselves to system-to-system integration for the moment.
Karol:
Maybe we'll dive deeper into nuances, but let's start there.
Karol:
A lot of architects think that integration is simply exposing rest endpoint.
Karol:
Now, if we integrate a system to a system, so let's assume we have a SaaS solution.
Karol:
It exposes an array of APIs, and we call that API from another system to do something, whatever that may be.
Karol:
At this point already, what kind of coupling we can expect and should consider as architects?
Vlad:
Yeah, so, at this point, we don't have all the answers, obviously, but we have some questions to ask.
Vlad:
So, first of all, that API is our integration contract, something that we're using for integration.
Vlad:
That's what we know about that upstream system.
Vlad:
That's how we are integrating so we know what is the integration contract.
Vlad:
The question is, what is reflected by that integration contract?
Vlad:
If that integration contract is based on the model of that business domain that is being used internally in that upstream system, and that model is exposed through the API by using the same semantic terms, then what's going to happen if they need to evolve the model?
Vlad:
Well, it's going to affect the API.
Vlad:
In that case, we have a breaking change.
Vlad:
Yeah.
Vlad:
So, now we have in that case, we'll have not contract coupling, but model coupling, because we have the knowledge of that model.
Vlad:
Now, what if in order to work with that API, I have to know something about how it functions internally?
Vlad:
Maybe there is some functionality that I have to duplicate in my system as well, because otherwise that integration won't work.
Vlad:
So, now we have two functionalities being implemented in that upstream system and me, the consumer, the downstream system.
Vlad:
Well, in that case, that functionality has to be changed simultaneously while we have a much higher level of knowledge that is being shared.
Vlad:
Now we have functional knowledge.
Vlad:
And ultimately, what if that system wasn't intended to be used through that API?
Vlad:
Maybe that's an internal API, and you just figured out that, hey, I have that system by other team.
Vlad:
They probably never intended other teams to integrate it with it, but I'll do it anyway.
Vlad:
In that case, we're intruding their encapsulation boundaries.
Vlad:
We're integrating with something that we shouldn't.
Vlad:
So, that's going to be intrusive coupling, including the encapsulation boundaries.
Vlad:
So, these four examples are four kinds of knowledge that can be shared across component boundaries whenever we have coupling.
Vlad:
Like contract coupling is the lowest, all the way to intrusive, which is like the highest.
Vlad:
And the more knowledge we are sharing, the higher the likelihood that when there is a change in the upstream, it will require a corresponding change in the downstream as well.
Vlad:
So, we'll have cascading changes.
Vlad:
We'll have a system that is a distributed monolith.
Vlad:
Like my project.
Vlad:
My first microservices endeavour.
Karol:
Fair enough.
Karol:
All right.
Karol:
I've been taking notes, but apparently my keyboard is louder than you speak, so I'm going to stop noting on my, well, clank keyboard.
Karol:
Okay.
Karol:
So, contract coupling would be the lowest, then, right?
Karol:
So, contract coupling means that we define a contract.
Karol:
We define a data model for exchange of information.
Karol:
And from a perspective of the one providing an API, that would be some sort of a, in the best case scenario, that would be some sort of a open host service in DDD nomenclature, where we have a published language, which published language is the specific definition of an object that we're exchanging or a service that we're invoking, whatever that may be, right?
Vlad:
Yeah, yeah, exactly.
Vlad:
That's the beauty of domain driven design.
Vlad:
It has answers for all the questions.
Vlad:
It just takes time to get familiar with all that terminology.
Vlad:
So, yeah.
Vlad:
Open host service, that means that we have a bounded context, like service system, that exposes an integration contract that is like a model of a model.
Vlad:
It's a model of their implementation model, which means the implementation model can change without necessarily causing corresponding changes in the integration contract.
Vlad:
And it also allows us to use multiple integration contracts, or in DDD terms, multiple published languages.
Vlad:
So, we can expose two versions of the API that will work with the same implementation model underneath.
Vlad:
So, yeah.
Vlad:
That's contract coupling in domain driven design.
Karol:
And this, what we talked about in terms of domain driven design, that's the general term for these phrases is context mapping, just to put it in perspective.
Vlad:
Yeah.
Vlad:
So, in strategic domain driven design, we're dealing with coarse grain design decisions.
Vlad:
We're identifying business subdomains, identifying their types, so that we'll be able to make smarter design decisions later on.
Vlad:
And we also design coarse grain components of our system.
Vlad:
They can be microservices, but they don't have to be microservices.
Vlad:
Bounded contexts can be wide.
Vlad:
Call them modular monoliths.
Vlad:
It doesn't matter.
Vlad:
Now, once you have those bounded contexts, they cannot be independent.
Vlad:
If they will be fully independent, they won't work together, that's not going to be a system.
Vlad:
They have to work together.
Vlad:
Now, how are we going to integrate them?
Vlad:
That's not a trivial question.
Vlad:
And to answer that question, domain driven design provides us with that notion of context mapping.
Vlad:
Like, how do we map the integration of different contexts?
Vlad:
And there is a number of patterns that fit different situations.
Vlad:
Some patterns are for cases when we have, let's say, well-established collaboration between teams in terms of those bounded contexts, and others when, you know, we have some organisational friction between the teams, and we have to address that in our software design.
Vlad:
So, that's overall called context mapping in DDD.
Karol:
For those who want a quick cheat on context mapping, there's a very nice repository on GitHub from DDD crew, and you can have, there's a very nice large picture with a cheat sheet of all those different types of context mapping patterns that we're talking about right now.
Karol:
So, feel free to scan the code and grab it, or just Google DDD crew context mapping right now, just to have that context for yourself.
Karol:
All right.
Karol:
Now, if we're looking further, so we had contracts, we have open host service, that's the best case scenario, pretty much, that we can have.
Karol:
So, the lowest form of contract that we can have here.
Karol:
And then, if we go down into the model.
Karol:
So, if I recall my good old days when I was still working with XML, XSDs, and WSDL files, of course, now you can do the same in open API specification.
Karol:
We use namespaces, a lot of them.
Karol:
So, if I wanted to have the API definition separated from the actual model that it was underneath, at least the data model, because that data model only composes the part of the model, right?
Karol:
Then I use two different namespaces, and I could completely separate them, and the internal data model could be different, could be bigger than the one that was exposed.
Karol:
Now, a sin that I did back in the day as a, I believe, junior developer still, when I was still working on integrations very actively, one time I exposed the internal namespace in the API.
Karol:
And then, let's talk about what happens then.
Karol:
What are the consequences of such a exposition?
Karol:
Because then we jump into the model coupling, literally, right?
Karol:
So, what are the consequences of this?
Vlad:
So, first of all, you're saying you did it by mistake, which naturally puts you in a great position, because I know many people making that on purpose.
Vlad:
True.
Karol:
Now, I was very much aware that this was a mistake, and I managed to fix it four years later, but that's how long it took to fix it.
Karol:
I see.
Karol:
To find the budget and to actually touch that part of the integration to make it happen, that required a lot of planning with other systems to actually refactor this.
Vlad:
Yeah.
Vlad:
So, here, domain-driven design, first of all, domain-driven design says that once you're exposing your model with distant teams, distant consumers of your API, whenever you will want to change that model, well, you will have to negotiate that change with them, because they have that knowledge.
Vlad:
They do know what your model looks like, and now you want to change it.
Vlad:
So, in order for them to understand the newer version, you have to coordinate that with the second team.
Vlad:
That's why domain-driven design puts emphasis on protecting that knowledge within bounded context.
Vlad:
We have open host service, we have anti-corruption layer, which is similar but from the other way around.
Vlad:
Now, at the same time, and that's the beauty of domain-driven design, this methodology says, but you don't have to be way too strict about that, because there are cases where you can round corners, and that's fine.
Vlad:
For example, let's say that you're implementing like core functionality of the business, something that is the company's core competitive advantage.
Vlad:
That functionality is the reason why your customers are choosing your solution and not your competitors.
Vlad:
Well, in that case, your business will want to optimise that solution to make it better all the time.
Vlad:
Why?
Vlad:
Because those annoying competitors, they will try to copy whatever you're doing, and you want to stay ahead, so you will have to change frequently.
Vlad:
So, that model, you want to be able to evolve it as efficiently as possible.
Vlad:
On the other hand, there are different business functionalities, which are not truly that interesting from the competitiveness standpoint.
Vlad:
In DDD lingo, they're called supporting, supporting subdomains.
Vlad:
This is the stuff that is boring.
Vlad:
And every system has those functionalities.
Vlad:
You just have to implement, because you don't have any other choice.
Vlad:
If there would be an open source on GitHub, you would love to take it and put it in there.
Vlad:
But there is no such solution, so you have to, you know, five years ago, I would say, you probably could just outsource that.
Vlad:
Today, well, cloud, here's what we need.
Vlad:
And that would work perfectly.
Vlad:
Why?
Vlad:
Because usually, these boring functionalities are also simple.
Vlad:
There is no complexity in the business requirements here.
Vlad:
So, cloud, do the job.
Vlad:
Let's deploy.
Vlad:
Now.
Karol:
And on top of being simple, they're quite repetitive most of the time.
Karol:
So, basically, if they're repetitive, then all the lovely LLMs have plenty of source material to learn it.
Karol:
Because they cannot learn core domain functionalities, because that's our business differentiator.
Karol:
So, it's not going to be the same.
Karol:
Right?
Karol:
And in supporting generic domains, that's plenty of that.
Vlad:
Yeah.
Vlad:
Supporting subdomains, there are usually data entry screens, like those tables that you have to populate, or upload materials, or ETL jobs, like take data from here, do some little manipulation, put it there.
Vlad:
That's it.
Vlad:
Not like a real business algorithm with some business complexity.
Vlad:
Now, why is it important in the context of the question you asked previously?
Vlad:
Well, this thing, nobody cares about it.
Vlad:
It's not going to change frequently.
Vlad:
So, if you expose that model, that's fine.
Vlad:
You are not going to suffer that much compared to the core business functionality.
Vlad:
Now, the important thing, however, is to draw the line, to identify the two cases.
Vlad:
Because again, I've seen companies running that corner, exploiting the models, and that works fine.
Vlad:
Nobody complains about it, because those are subdomains.
Vlad:
So, hey, that works for supporting subdomains.
Vlad:
Let's do it for our core business functionality.
Vlad:
And guess what?
Vlad:
Nope.
Vlad:
Nope.
Vlad:
Yes.
Karol:
Let me guess.
Karol:
The word would be volatility.
Karol:
Yes.
Vlad:
The volatility, the rate of changes in core subdomain is way higher than supporting subdomain.
Karol:
Talking about subdomains, where would you place an integration platform?
Vlad:
An integration platform?
Karol:
Yes.
Karol:
So, ah, okay.
Karol:
That's my favourite answer.
Karol:
Go on.
Vlad:
No, that's it.
Vlad:
That's the answer.
Vlad:
It depends what kind of integration that is.
Vlad:
Because there are integrations that are simple.
Vlad:
Like, there's nothing really interesting about it.
Vlad:
Like, in terms, you at most implement anti-corruption layer.
Vlad:
You take the model that is exposed by the upstream, do some modification on top of it, and here you have your data.
Vlad:
That's it.
Vlad:
So, that would be like supporting flavour.
Vlad:
But I've also seen companies that didn't have any core subdomain, like, in its regular sense.
Vlad:
Like, there is no business algorithms, nothing really interesting.
Vlad:
However, the integration magic they did about things that looked unintegratable, that was their competitive advantage.
Vlad:
So, in those companies, the integration was their core subdomain.
Karol:
Oh, interesting.
Karol:
Because I always consider integration platforms and integration as a field being mostly the supporting subdomain.
Karol:
The technology itself is generic, but what we do with that technology as a platform technology and how we build those integrations usually lands in my book in supporting.
Karol:
That's what I see most of the times.
Karol:
But that's an interesting view on it.
Vlad:
I will give you an example.
Vlad:
All right.
Vlad:
So, let's say you're implementing a system that is going to send receipts that you get in a shop as an SMS message.
Vlad:
So, basically, that system does integration of that cashier's computer or cashier's printer and whatever system you're using for sending SMS messages.
Vlad:
Is it trivial?
Vlad:
Hell no.
Vlad:
That's by far not a trivial system.
Vlad:
That's, like, complexity on top of complexity.
Vlad:
But in the heart of it, that's integration.
Karol:
Okay.
Karol:
That makes a lot of sense.
Karol:
Going back for a moment to AI, we have a nice question from David, or a colleague from SAP.
Karol:
Hello, David from Palo Alto.
Karol:
It's nice that you could join us.
Karol:
So, to what degree we can teach AI agents about DDD and coupling?
Vlad:
Yeah.
Vlad:
Hello, David.
Vlad:
Yeah.
Vlad:
That's a great question.
Vlad:
And the thing is, we shouldn't, at least now, trust whatever those models know about domain driven design and coupling.
Vlad:
Because that's, like, an average answer on Stack Overflow.
Vlad:
That's the level of knowledge.
Vlad:
Not the best answer on Stack Overflow, the average one.
Vlad:
Which is kind of, on Stack Overflow, you can see people saying domain driven design is about buying effective domain names.
Vlad:
Now, I'll tell you what works best for me.
Vlad:
And like with people, teaching the theory, but showing examples.
Vlad:
Like, here is what I mean by an aggregate.
Vlad:
And sorry, I'm going towards lower levels of abstraction.
Vlad:
But I have to now.
Vlad:
Yeah.
Vlad:
So, an aggregate.
Vlad:
If you ask it to implement an aggregate, it will do something.
Vlad:
Is it going to be like a proper domain driven design aggregate?
Vlad:
Who knows.
Vlad:
So, give it examples.
Vlad:
And that works.
Vlad:
Coupling, same story.
Vlad:
A friend of mine, Gregor, showed me as a repository with cloud skills.
Vlad:
And one of them is about evaluating modularity.
Vlad:
And for that, he uses the balanced coupling model.
Vlad:
So, he teaches the model to reason in terms of balanced coupling.
Vlad:
He says that what works for him is first iteration, first implementation of a codebase, do something that works.
Vlad:
And then use my skills to evaluate the problems in the design and improve it over time.
Vlad:
So, after, like, three or four iterations of improvement of refactoring, he says that the codebase looks almost as if he wrote it.
Vlad:
So, yeah.
Vlad:
I would say, David, yeah, you can teach them.
Karol:
So, basically, fine tuning or context engineering with giving examples, as David here comments further on the matter.
Karol:
When I use gen AI for a number of things, that usually is the approach to engineer the context and then provide examples, what I mean by specific terms.
Karol:
And that really speeds up work at times.
Karol:
Not always.
Karol:
Because, like you said, average answer.
Karol:
Not the best answer, but the average Stack Overflow answer.
Karol:
And in terms of the field of integration architecture, that's the average answer is way below the norm I would consider average, because AI just didn't have materials to learn from.
Karol:
And that's a completely different problem in that space.
Karol:
All right.
Karol:
Going back to our REST API that we started with.
Karol:
So, okay.
Karol:
We had model coupling.
Karol:
So, we exposed the exact same model.
Karol:
So, we create that brittleness that every time we change the model, we impact our consumers.
Karol:
Which is a problem on its own.
Karol:
Now, with an example of a functional coupling.
Karol:
And in my head, when I listen to you explaining functional coupling, I instantly it's popped into my head a API where there were optional elements.
Karol:
But because the structure of the API is very poorly designed, for example, it's a flat structure with optional elements.
Karol:
But there are dependencies between different elements that some elements need to exist, coexist with one another when you call, even though they're optional.
Karol:
And it's nowhere described.
Karol:
So, would that constitute the level of knowledge about the system and the implementation of said API to be already functional coupling?
Karol:
That I need to know how that system behaves underneath and what data does it really expect to work?
Karol:
Otherwise, it will return me an error that it's missing an element, even though all the elements were optional.
Vlad:
Well, that's an interesting question.
Vlad:
That's an interesting question.
Vlad:
So, if you have an API that is not explicit, what you're describing is a very implicit API.
Karol:
True.
Vlad:
Now...
Karol:
Many of these I've seen.
Vlad:
Yeah.
Vlad:
What I like to use for evaluating the complexity of or implicitness or explicitness of a contract, integration contract, or a model coupling is the static model.
Vlad:
So, Kinesans is a scale of evaluating components in object-orientated code.
Vlad:
That was the main goal at the time that model was introduced in the 90s.
Vlad:
And it has a number of levels, and all of them basically describe, okay, we have two components, one depends on the other, what the downstream needs to know about the upstream.
Vlad:
Does it have to know just the name, let's say, of a method or parameter?
Vlad:
Does it have to know the type?
Vlad:
If, let's say, a number has like magic value attached to it, like you pass seven, and that seven means not number seven, but order of status completed.
Vlad:
So, specific meaning.
Vlad:
That is also part of that model.
Vlad:
And the next level is, it has a very misleading name.
Vlad:
It's called Kinesis of algorithm.
Vlad:
And this one is actually about those quirks that you have with implicit interfaces.
Vlad:
And it kind of reminds me of that one, I would say.
Vlad:
And that puts us either in integration contract, contract coupling, or model coupling, not functional coupling.
Vlad:
So, functional coupling, it's not about functional coupling, it's not about the data structures.
Vlad:
It's about the behaviour of a system, something, the behaviour that it implements, and the knowledge about that is being shared with a downstream consumer.
Vlad:
Now, when we're talking about this level of abstraction, luckily, luckily, examples of this level of coupling are not that common.
Vlad:
But, we still have them.
Karol:
So, I just pulled this out of O'Reilly straight from your book.
Karol:
So, these are the levels of coupling, and then the Kinesis of name, type, meaning, algorithm, and position.
Karol:
So, where algorithm is here in the contract coupling, then if we're talking about functional coupling, then it's a different set of Kinesis.
Vlad:
Yeah, but pay attention that static Kinesis, it's used for degrees of contract coupling, but also of model coupling.
Vlad:
So, it's all about the intent.
Vlad:
Kinesis on its own, it communicates, okay, what type of, from the technical perspective, what do I need to know?
Vlad:
Now, with that differentiation between contract and model coupling, we're saying not only technically, but business-wise, what that term or what that piece of knowledge means.
Vlad:
Does it belong to an integration model or the implementation model?
Karol:
Right, and this is why in contract coupling, we also have the Kinesis of meaning, because I think it's worthwhile to mention that, first of all, coupling is a spectrum, as we see here on the shown diagram, but also it's not that all coupling is bad.
Karol:
There are types of coupling that are actually very much wanted, like contract coupling and the Kinesis of meaning in that contract coupling, because without it, we wouldn't be able to do any business over APIs.
Vlad:
Yeah, actually, I would even argue that there is no bad level of integration strength.
Vlad:
So, this model, I call it integration strength.
Vlad:
It describes different levels of knowledge.
Vlad:
Now, even when we're looking at that big one on the right-hand side, intrusive coupling, we can still find examples of scenarios in which that is going to be the effective design.
Vlad:
So, I wouldn't, well, I hear people label like this is, this level of Kinesis is the bad one, you have to avoid it.
Karol:
Yeah, it may be wanted or unwanted, but then it depends on the context we're in, right, because sometimes it will be very much wanted.
Karol:
In my world, when I do application integration between various domain systems, I usually want to limit myself to contract coupling.
Karol:
But this is on a very large distance, and I don't want to share that knowledge over large distances.
Karol:
But if I would be doing, I don't know, a small application over my Google workspace, because I automate the hell out of my Google workspace, then intrusive coupling is perfectly fine in that case, from my perspective.
Vlad:
Yeah.
Vlad:
So, as you said, it depends on the distance, the physical distance between coupled components.
Vlad:
If it's a big one, yes, like in your example of systems, you want to minimise the shared knowledge.
Vlad:
Unless, as we mentioned previously, the upstream, the source of knowledge, is not going to be volatile.
Vlad:
It is not going to change.
Vlad:
In that case, if that will free up time and effort that you can invest in core business, invest it there.
Vlad:
Just the simplest thing here, where volatility is low.
Vlad:
Now, I still have it on my stack, your question about functional coupling.
Karol:
Let's get back to it.
Karol:
Yeah.
Vlad:
So, let's imagine you have, you're exposing an API.
Vlad:
And that API receives some field.
Vlad:
And that field has some non-trivial validation rule.
Vlad:
Maybe it's, you know what?
Vlad:
Email.
Vlad:
Like, simple email.
Vlad:
So, we have an email that should be passed.
Vlad:
However, internally, only Google email addresses are supported.
Vlad:
So, maybe they're ending with Gmail, or maybe it's Google for domains.
Vlad:
I don't know.
Vlad:
I encountered that.
Vlad:
So, the API looks like, okay, I can pass any email, but only Gmail works.
Vlad:
Now, whenever that internal implementation will change, if they add support for, I don't know, Microsoft Live emails, that's going to affect the functionality that can be implemented by the consumer.
Vlad:
So, that's kind of borderline example of functional coupling.
Vlad:
Now, we can take it, the same example, in different context, can be even contract coupling.
Vlad:
But the case that I'm basing it on, like, real life case, that was an example of because I'll explain.
Vlad:
The consumer had to support the same platforms implemented by the upstream.
Karol:
That I actually seen that in practise.
Karol:
Only the other way around.
Karol:
It's not about having a specific platform.
Karol:
It's excluding a specific platform.
Vlad:
Oh, even worse.
Vlad:
Okay.
Vlad:
Even worse.
Karol:
Because I remember registering for a trial account with one technology.
Karol:
And to register, and that technology also, when you register to the academy, they offered certifications for free.
Karol:
Which was very lucrative.
Karol:
But because they had too many people registering, just to get the certifications for free, and they cheated the hell out of the certifications because they were not proctored, so they decided that they allow registration only with company emails.
Karol:
So, if you have the popular email, like Gmail, Hotmail, or any other this kind of an extension that is a common extension from a public email service, then you couldn't register.
Karol:
So, that you fill out the form, you call the API, and the API says, sorry, you cannot register.
Karol:
So, I think that's an example also of the functional coupling in that sense.
Karol:
Because then the form actually, the frontend had to implement specific error handling to handle that somebody sent in the data that are not validated.
Karol:
But they didn't implement any validation on the form itself.
Karol:
Which was interesting.
Vlad:
Yeah.
Vlad:
Again, examples of functional coupling on that level of abstraction are pretty rare.
Vlad:
But again, they exist.
Vlad:
If we get back to my second favourite topic, domain driven design, then we have, like, a pattern.
Vlad:
Not an entire pattern.
Vlad:
A pattern.
Vlad:
In domain driven design, specifically, that teaches you how to do it.
Vlad:
How to implement functional coupling on that level of abstraction.
Vlad:
And people who are familiar with domain driven design may already figure that out.
Vlad:
That separate waste pattern.
Vlad:
That's the case of you have two bounded contexts that are owned by different teams.
Vlad:
And people in these teams, maybe they hate each other.
Vlad:
Maybe they locate it in different time zones.
Vlad:
Or for any other reason, they cannot collaborate.
Vlad:
So, the idea says, okay, in some cases, don't force them to collaborate.
Vlad:
Instead, just let them duplicate their own functionality.
Vlad:
As long as that functionality doesn't block the core subdomain.
Vlad:
In that case, that's going to be a pain.
Vlad:
If it's generic, if that's supporting, let them do it.
Vlad:
We'll have functional coupling.
Karol:
And this is where Conway's law comes to play a lot.
Karol:
So, that we organise our architecture according to the team composition, not the other way around.
Karol:
That's where a lot of other things come to play where we actually, especially in large corporate environments, when there is a lack of communication between different departments, different lines of services.
Karol:
And we get shadow ITs.
Karol:
And then we have those separate ways.
Karol:
Not only because people hate each other, but because they just don't know that they exist.
Karol:
And this is a lovely mess.
Vlad:
That's a dangerous mess.
Vlad:
In that case, they can end up duplicating core subdomains.
Karol:
I don't believe I've ever seen that, but you're absolutely right that this could be a non-trivial risk.
Karol:
That would be hellish to dismantle.
Karol:
Now, okay.
Karol:
If we're looking at functional coupling or even intrusive coupling that is
Karol:
unwanted, and if we mitigate by having separate ways, or we have that shadow IT,
Karol:
looking at domain-driven design and looking at coupling problems, especially the invisible
Karol:
coupling, because there is a kind of coupling that is not visible, especially if we have
Karol:
two or three teams implementing the same functionalities,
Karol:
maybe not knowing about each other, then how to even get into that and try to dismantle that?
Karol:
Especially that this kind of pathological coupling, it's very, very hard to identify.
Vlad:
Yeah.
Vlad:
Yeah.
Vlad:
It is very hard to identify.
Vlad:
And as Eric Evans said years ago, not all of large systems are going to be well-designed.
Vlad:
That's something that we have to just understand, agree, and live with that.
Vlad:
That's a rule of life.
Vlad:
There will be entropy somewhere in the system, but with domain-driven design, what we can do is we can steer that entropy to parts of that system that don't really matter, like supporting subdomains or ex-subdomains.
Vlad:
If we can do it, that's it.
Vlad:
We did our job as designers, as architects, whatever.
Vlad:
So, going back to your question, how do we dismantle it?
Vlad:
I would say that that's my first answer when people ask me about domain-driven design.
Vlad:
How do I introduce it?
Vlad:
We have that system, its legacy, it's been implemented for X amount of years.
Vlad:
And we have turnover of engineers.
Vlad:
What do we do now?
Vlad:
Well, you are not going to tell Cloud to rewrite it and make it perfect.
Vlad:
Like, hey, Cloud, I want this to be domain-driven design.
Vlad:
Go ahead.
Vlad:
Or even Ralph, it's not going to work.
Vlad:
So, instead, what we need to do is to identify pain.
Vlad:
Now, that can sound funny, like pain in the system.
Vlad:
Well, I'm that serious.
Vlad:
And identifying pain is important and it can also be difficult, because in those types of companies, people get used to pain, so they don't feel it anymore.
Vlad:
They're like, okay, yes, so I want to change the colour of a button and it's going to break something in that team.
Vlad:
And yeah, I have to do that first.
Vlad:
I've been doing it for years, yeah, and I'll do it for another year.
Vlad:
So, that's integration pain.
Vlad:
But people are not noticing it.
Vlad:
So, as an external consultant, I believe that our goal is to identify, help them identify those pain points to make them as explicit as possible.
Vlad:
To get an agreement that, hey, you have a problem here.
Vlad:
That's something that makes you less effective.
Vlad:
And once you have that agreement on the problem, well, we can discuss an agreement on a solution, how to change it.
Vlad:
Now, change that depends.
Vlad:
Some people are scared of domain-driven design.
Vlad:
Nothing you can do about it.
Vlad:
People hear domain-driven design, they hear complexity, bound of context, aggregates.
Karol:
I think a lot of people are scared of the word complexity or the word governance.
Karol:
And it's like, they hear governance, you start talking about, okay, we need to implement some sort of governance over this.
Karol:
And they go like, no, no, no, no, no.
Karol:
We don't need more governance.
Karol:
And it's not that they don't need governance, they just didn't have good governance over things, they just had the management.
Karol:
Yeah.
Vlad:
Yeah, so, people have different traumas.
Vlad:
We have to adapt the solution we are proposing not to trigger their traumas, their PTSDs.
Vlad:
And if people are afraid of domain-driven design, well, that's fine.
Vlad:
I can talk to you in terms of coupling.
Vlad:
So, we have here a model that travels long distance and its source is volatile.
Vlad:
What can we do about it?
Vlad:
Can we make the source less volatile?
Vlad:
Yes or no?
Vlad:
No?
Vlad:
Okay.
Vlad:
So, let's shorten the distance.
Vlad:
Or maybe we can reduce the knowledge.
Vlad:
If not, shorten the distance.
Vlad:
That's the coupling terminology.
Vlad:
I love it because of its effectiveness.
Vlad:
Now, domain-driven design, if they're not afraid of it, okay, let's talk about models.
Vlad:
Like, what's going on?
Vlad:
Why do we have those, maybe, cascading changes?
Vlad:
Maybe we have coordination issues.
Vlad:
Maybe we have constant friction between teams.
Vlad:
All those issues can be addressed by picking the right DDD pattern.
Vlad:
And again, you don't have to refactor the whole thing.
Vlad:
Just identify strategic areas that really, really beg for improvement.
Vlad:
Prove them.
Vlad:
Like, do the 20% of work that will bring you 80% of the value.
Karol:
But for that, you need to really identify them and model them out, right?
Karol:
So, which of the tools available would you use to identify, to do that discovery?
Vlad:
Yeah.
Vlad:
So, there is one tool and it's the hardest, at least for me, because I'm an introvert and that's talking to people.
Vlad:
Like, having those conversations, like really understanding what annoys you, what makes you less effective, what are the frictions.
Vlad:
And sometimes people are afraid to tell you because politics.
Vlad:
They don't want to sound like the one who complains about everything.
Vlad:
So, yeah.
Vlad:
I try to figure it out.
Vlad:
Exactly.
Vlad:
Yeah.
Karol:
And then Philip continues.
Karol:
If you're here for the first time, you have to model.
Karol:
Fight for the win.
Karol:
Yeah, but Philip is my co-author of the DDD training and he's very versed in DDD and he's a DDD coach.
Karol:
So, he can be a smarty pants about it in comments because he went through all those dramas related to domain discovery, et cetera, going into event storming and using those tools on a lot of conversations.
Karol:
And you're right.
Karol:
This is, yeah, for an introvert, that's definitely something that may be problematic.
Karol:
And I'm not the one to enjoy these conversations always myself.
Karol:
I do instigate them often, but sometimes they can be very, very difficult.
Karol:
That's very true.
Karol:
Because literally when we were doing that domain discovery, we're touching the really painful parts.
Karol:
That's what I see at least.
Karol:
And speaking about the painful parts, can you tell us a little bit about the sociotechnical and social organisational aspects of coupling?
Karol:
Because I think these are the parts of coupling that very few people talk about.
Karol:
And I know that you have plenty of stories on that to explain that and tell us how this actually works because they are also, in my opinion, very relevant, not only for interoperability topics of integration architecture, but for running a company and actually using domain systems to run the company and do business.
Vlad:
Yeah.
Vlad:
Yeah.
Vlad:
That's a great question.
Vlad:
It takes us back to the notion of distance.
Vlad:
Okay.
Vlad:
So we have knowledge that travels from component A from the upstream to component B, the downstream.
Vlad:
Now, what is the distance that is being travelled by that knowledge?
Vlad:
If they are close to each other, maybe within the same module, maybe even within the same file, the distance is low.
Vlad:
If you have to change them simultaneously, that's going to be easy.
Vlad:
Like they're close to each other.
Vlad:
It's almost like modifying one thing.
Vlad:
On the other hand, we have, let's say, the other extreme that you mentioned.
Vlad:
We have two systems or maybe two services in an enterprise company.
Vlad:
Now, those two services are different code bases, different projects, different repositories probably.
Vlad:
And if they have to change simultaneously, then, well, now you have some effort that you need to invest to make the change happen, because you have to coordinate that change across that distance, across those components.
Vlad:
And of course, that also induces cognitive load.
Vlad:
It makes it easy to forget that there is that distant part of the system that has to change as well.
Vlad:
So you will just change what you remember of, deploy it, and see the fireworks when you deploy to production.
Vlad:
Now, that's the technical aspect of it.
Vlad:
And as with everything in our job, things become more complicated because of people.
Vlad:
Now, let's introduce people into that equation.
Vlad:
So we have, let's say, two bounded contexts, being integrated, sharing knowledge, sharing lots of knowledge, and they have to co-evolve.
Vlad:
For reasons.
Vlad:
Let's say that they are sharing knowledge of model.
Vlad:
Kind of no-no in DDD world, but let's say that that's our scenario.
Vlad:
We have two bounded contexts, model coupled to each other.
Vlad:
The model changes one, the second one has to implement the corresponding change as well.
Vlad:
Guess what?
Vlad:
Although that sounds like a no-no in domain driven design, in domain driven design, that's actually an integration pattern, part of context mapping.
Vlad:
That's called partnership.
Vlad:
In partnership, two teams implement ad hoc integration.
Vlad:
They just integrate somehow.
Vlad:
Whenever that integration doesn't work, they will resolve that integration issue through collaboration, through conversations, through helping each other.
Vlad:
Now, when that pattern is not going to work?
Vlad:
Well, when those two teams don't have that well-established collaboration.
Vlad:
In that case, that pattern is not going to work.
Vlad:
Now, let's talk, what is the difference between the two scenarios?
Vlad:
Well, first one, those two bounded contexts could be implemented by one team.
Vlad:
Can they collaborate with themselves?
Vlad:
Probably, yeah.
Vlad:
So, in that case, the distance is kind of, let's say the distance between the people is short.
Vlad:
So, we have the technical distance plus the personal, interpersonal distance.
Vlad:
That one is short.
Vlad:
Maybe these are two teams sitting in the same room because that's a small startup company, they're maybe working out of the garage, and they really try to help each other because that's their only chance to collaborate.
Vlad:
That pattern will work.
Vlad:
Again, the social distance is low.
Vlad:
And maybe they succeeded, and that company has grown into an enterprise.
Vlad:
And now, those two bounded contexts, same bounded context, belong to two teams that are maybe they're in different geographical locations.
Vlad:
Maybe they're in the same building, but they just have different goals, and they don't want to collaborate.
Vlad:
Well, in that case, domain-driven design says, hey, you have a problem, partnership won't work in that case.
Vlad:
You have to use a different kind of relationship, either open host service or anti-corruption layer, or in the worst case, separate ways.
Vlad:
Now, what does it mean in the language of coupling?
Vlad:
Well, if we have well-established collaboration, model coupling can work.
Vlad:
If people are not willing to collaborate, then we have to reduce the knowledge.
Vlad:
The distance is bigger, we have to reduce the knowledge.
Vlad:
We have to go to contract coupling, open host service, anti-corruption layer in domain-driven design terminology.
Karol:
Yeah.
Karol:
So basically, you're saying if we can maintain a very short social distance that we can manage tight coupling.
Karol:
But if the social distance is high, we will not be able to effectively manage that kind of tight coupling between two different systems, modules, or whatever we have coupled.
Vlad:
Look, again, you know the answer.
Vlad:
It depends.
Vlad:
So I've been in a situation in which a team of three people implemented a huge, huge, like not monolith, like a huge big wall of mud.
Vlad:
They were close to each other, but the technical distance was already way too big, so it induced too much cognitive load, and that close social distance didn't help.
Vlad:
Like, if you have infinity and you increase it by zero, well, guess what?
Vlad:
You still have infinity.
Vlad:
So it didn't help.
Vlad:
Now, in my previous example, what I meant is you can make some pragmatic decisions to round some corners.
Vlad:
So bounded contexts, you probably don't want to share functional knowledge.
Vlad:
You can share model knowledge to a degree.
Vlad:
Like sharing integration contract, that is a perfect case.
Vlad:
Startup companies, guess what?
Vlad:
Not always you have time.
Vlad:
Sometimes you have to be pragmatic.
Vlad:
So in those cases, what I'm saying is if the social distance is managed, then yeah, it can work if you're around the corner.
Vlad:
But you have to watch for organisational changes, because organisation grows, change, yeah, and it's going to make your design decisions that yesterday a disaster tomorrow.
Karol:
I've been in a company once that was acting like a startup, and they assumed that the social distances were very low, and they required tactical decisions all the time.
Karol:
Speaking about architecture and proper patterns in engineering was frowned upon.
Karol:
And of course, they suffered through that horrendously, because they had so many tight dependencies between different teams that at a point, they couldn't even manage that.
Karol:
So that heavily influenced the code base of all the teams that work in a completely separate modules and completely different things functionally.
Karol:
And just to weigh in here, we have the user with a lovely name left toe, getting lost in our conversation, because we're flowing towards people management, I think it's worthwhile just to reiterate that software as it is, it's not just an art form that we just sit down and write software, that software usually has a purpose.
Karol:
And that is a business purpose.
Karol:
And it comes from people.
Karol:
If people don't align on the purpose of the software and on the requirements on the dependencies, then we're going to have a problem that influences our architecture, and development and testing and the actual end result and usability of that software.
Karol:
And even if at first it is usable, then because we have those dependencies that different types of coupling, then we'll have a problem later, because it's not going to be scalable, it's not going to be extensible, or whatever other characteristic we're diving into.
Karol:
And I see the YouTube comments were started to go crazy to the extent that I'm not able to keep track because they started talking about the trolley problem and railroads all of a sudden.
Karol:
So, aligning teams as a railroad, and everybody has their own tracks.
Karol:
So, YouTube is going crazy tonight.
Karol:
That's absolutely cool.
Karol:
So, we could have a laugh.
Karol:
Instead of dad jokes, we have YouTube comments going in to have a laugh about.
Karol:
Great comments, by the way.
Vlad:
Yeah, that's a cool way to model it.
Karol:
And they're basically on point of the discussion.
Karol:
Absolutely.
Karol:
And especially this one.
Karol:
People management and organisational management and making organisational changes is an integral part of design.
Karol:
Without stakeholder management, we can't really do proper design, because if we don't identify those key stakeholders that we depend on for the success, we're probably going to fail.
Karol:
But that's, again, a different part of it that is not exactly coupling coupling, but this part of DDD where you need to bring the right stakeholders, the right people with knowledge into the room to model out the behaviour, model out the business process, model out the bounded context domain and the dependencies between them.
Vlad:
I can take it towards coupling.
Vlad:
No problem at all.
Vlad:
Please do.
Vlad:
So, what domain driven design tells us?
Vlad:
It says at the core of strategic domain driven design, we have to cultivate ubiquitous language.
Vlad:
We have to build a shared understanding with domain experts, and we should do it by that annoying way of speaking with them and building that shared language in the language that business people understand.
Vlad:
Now, in DDD, that's called ubiquitous language.
Vlad:
So, ubiquitous language basically reflects their mental model.
Vlad:
So, we're using the same model of the business domain to communicate with them.
Vlad:
Now, if we're not going to do it, if, on the other hand, we'll try to build one canonical model of the business that's going to address all use cases of the system, no matter what business stakeholder it addresses, well, guess what?
Vlad:
When you will communicate with that domain expert, you will have to use different models, models that are not related to that stakeholder's perspective.
Vlad:
So, that knowledge will flow in that conversation.
Karol:
And given that we all have a slightly different model of reality anyways, because we all model whether we want it or not, it's always a matter of aligning those models.
Karol:
And without talking about those models, we will definitely have different models in our heads.
Karol:
One of the exercises I always do with people at the beginning is, okay, but what do you mean by this term?
Karol:
Please explain, because it may be a common term, but maybe also commonly misunderstood.
Karol:
And then I have an assumption that this is this and this, and my assumption may be wrong, but I'm making those assumptions because I have already a model in my head.
Karol:
And that's, oh, what is integration?
Karol:
That's my favourite.
Karol:
I've been in the company where the word integration meant at the same time, application integration and data integration.
Karol:
Imagine the confusion, because these are completely two different things.
Karol:
People absolutely did not know what they were talking about.
Karol:
And there were literally some people that thought that data integration and application integration is one and the same.
Vlad:
Yeah, that's the beauty of domain-driven design.
Vlad:
Like, come on, talking to people, that's common sense.
Vlad:
Speaking with people in their language, that's common sense.
Vlad:
And that's like the main critique I hear about domain-driven design.
Vlad:
That's just common sense with pencil labels on top of it.
Vlad:
And I'm like, oh, really?
Vlad:
So why the majority of people are not using that common sense?
Vlad:
Why is that common sense not that common?
Vlad:
Why are you not doing it?
Karol:
Yeah, and again, the joke I make on trainings myself, if you put four architects in the room, you'll have five different opinions, exactly like Toasty here says about six explanations from five different people.
Karol:
And that always happens.
Karol:
Just yesterday, I've been asking a group of architects, what is extensibility?
Karol:
And I had literally a group of four people just sitting in that part of the room, I had five different opinions of what is extensibility as an architectural characteristic.
Karol:
Nobody could give me a straight answer.
Karol:
They started just talking about it and trying to figure out what is actually extensibility.
Karol:
And that's the usual case.
Karol:
And this is why ubiquitous language I find very important.
Karol:
But then again, it's context specific.
Karol:
So it always, it depends.
Karol:
Because you go to as a consultant, and you're a consultant yourself, in that sense, right?
Karol:
You go to one company, the same terminology will mean something else.
Karol:
And then the other one, the same terminology will mean something else.
Karol:
You need to, as that consultant, you need to adapt to that terminology.
Karol:
You cannot bring your own to an extent.
Karol:
Yeah.
Vlad:
Yeah.
Vlad:
Like we discussed, you come to a company, okay, so what do you mean by a software architect?
Karol:
Yeah.
Karol:
And then the names for a software architect, there's so many, right?
Karol:
And the roles and the responsibilities and the...
Karol:
Yeah, that's a whole different topic.
Karol:
We can refer to a video from Mark Richards, just on that single topic, where he just rants about different roles, and the maybe general understanding of what those roles mean.
Karol:
But that's a, this one actually we can put into coupling very easy.
Karol:
Because that's basically semantic coupling.
Vlad:
Yeah.
Karol:
So the connaissance of meaning.
Vlad:
Yeah.
Vlad:
So it depends.
Vlad:
If you're using the model.
Vlad:
Okay.
Vlad:
So if you're communicating in the same model, then yeah, that's model coupling.
Vlad:
Now, if you're talking to someone else who is not familiar with that shared language, and you have to simplify it, but you still have to explain what happens in that business domain.
Vlad:
Well, you simplify it, maybe you remember that episode of The Office with Michael Scott, when they had to explain the accountant, had to explain him what's going to happen if they're not going to spend all the money by the end of year, so next one will get less.
Vlad:
And he said, like, I don't remember exactly.
Vlad:
But he explained like he was six years old or something like that.
Vlad:
So that was like an integration contract.
Karol:
A approximation of a model to be able to convey that message.
Vlad:
Yeah.
Karol:
And now we're going to get independent joke in chat.
Karol:
Perfect.
Karol:
That's, that's what we're aiming for.
Karol:
I find it the most right answer in architecture anyways, it depends.
Karol:
Then we can go cracking.
Vlad:
Oh, well, usually, if you explain what it depends on, then that's fine.
Vlad:
If it's just it's annoying.
Karol:
Yeah, I, we tend to talk about the seniority level of different people.
Karol:
If you're a junior, you have an answer for a question.
Karol:
If you're a meteor, then you'll say it depends.
Karol:
If you're in senior, you'll say it depends.
Karol:
And you'll start explaining on the walk.
Karol:
And this is a show of, does somebody really understand the topic that they're talking about in that sense?
Karol:
But that's a completely different ballpark.
Karol:
Now, where were we in terms of coupling again?
Vlad:
So the last question was about people, about social interactions.
Karol:
Yes.
Karol:
So if you, if we put it in the context of Conway's law, can we explain coupling using Conway's law?
Karol:
That, because that might be an interesting one.
Karol:
Yeah, that's interesting.
Karol:
You recall Conway's law or should I just bring it up?
Vlad:
Yeah, of course.
Vlad:
I'm not going to say it word by word.
Vlad:
I don't remember it, but.
Karol:
Don't worry.
Karol:
I have it handy.
Vlad:
The architecture is going, one day is going to mimic the architecture of the company, their organisational structure.
Vlad:
Yeah, again, organisational structure makes some people closer to each other.
Vlad:
So the distance is reduced.
Vlad:
Some are more distance from each other.
Vlad:
So they're not going to collaborate.
Vlad:
So as a result, the technical distance will be affected as well.
Karol:
So I always, when I'm asked about Conway's law and I heard this story about an architect designing a system.
Karol:
Okay.
Karol:
So I'm designing the system.
Karol:
I don't know what it's going to do yet exactly, but I know it's going to have six modules because I have six teams in different geographical locations.
Vlad:
Okay.
Karol:
So it's definitely going to have six modules.
Karol:
I don't know which module was going to do what yet, but it's going to be six modules.
Karol:
So I think that puts that perspective on the social technical coupling here, social organisational coupling, because we basically looking at that, we're having that spread of teams all over the place.
Karol:
That would then mean that we want to have them going separate ways or well at best separate ways, because we already anticipate the problem from Conway's law, but we might as well go consumer provider or something like that, or partnership at times if they are closer, right?
Vlad:
Yeah.
Vlad:
So in domain-driven design terms, if you have six teams, that means you will have at least six bounded contexts.
Vlad:
Bounded context is boundary.
Vlad:
You should never have the situation in which multiple teams work on the same bounded context because you want to maximise the effectiveness of sharing knowledge, of exchange of ideas, of people working on the same model.
Vlad:
And model is encompassed by a bounded context.
Vlad:
So at least you're going to have six bounded contexts.
Vlad:
Now, we don't know what they're implementing.
Vlad:
So maybe some of the teams might require even more bounded context because they're driven not only by organisational structure, but also by models.
Vlad:
Maybe they will discover conflicting models.
Vlad:
Let's say that a team implements multiple subdomains and to implement those functionalities, they need two different ways to represent real world entities.
Vlad:
They need multiple models.
Vlad:
Well, multiple models, according to domain-driven design, that means multiple bounded contexts.
Vlad:
And yeah, and of course you analyse the nature of those teams, how they are able to collaborate, whether they're willing to collaborate.
Vlad:
I would say that separate ways, it's something that you want to avoid as much as possible unless you absolutely must, just as shared kernel.
Vlad:
But yeah, it's, you know, everything new in our field was that we invented recently.
Vlad:
We just rediscovered it because people were talking about it decades ago.
Karol:
It's like hype cycles.
Karol:
Every time something pops up, we get to rediscover the same old things that were defined long time ago.
Karol:
I'm looking at certain aspects that pop up again and again.
Karol:
We've had microservices and the popularity, raising popularity of REST and JSON.
Karol:
And with that, we have to rediscover all that there was already described through XML and SOAP.
Karol:
And now we have AI agents and agentic ecosystems, and we're discovering APIs again, because we need APIs to serve the purpose for AI agents.
Karol:
And we discovered the importance of interoperability.
Karol:
And it's every few years, it's the same story, I suppose.
Karol:
I've been looking at it for 15 years now, and I already see the cycles go in and go in.
Karol:
It's quite interesting in that sense to look at it.
Vlad:
Yeah.
Vlad:
I would say that now we're entering the golden age of something that was introduced in late 60s, modularity.
Vlad:
Now, since those early days, we had trouble identifying what modularity really is.
Vlad:
How can you achieve it?
Vlad:
But there was no disagreement that modularity is important.
Vlad:
Now, modularity had different names.
Vlad:
Originally, it was modularity, then it was object-orientated programming.
Vlad:
The goal was modularity, but it was labelled as OOP.
Vlad:
Microservices, guess what?
Karol:
That's modularity.
Vlad:
Modularity, yes.
Karol:
But to be fair, on a different abstraction level.
Vlad:
Yes.
Vlad:
Yeah, that's true.
Vlad:
Now, we have those things that write code for us.
Vlad:
And those darn things are a bit stupid when they have to think about lots of things.
Vlad:
So, how are we going to tackle that?
Karol:
Modularity!
Karol:
Yes.
Karol:
Oh, my.
Karol:
Yes.
Karol:
And we're already looking at, at least in my field, that organisations are not willing to change the way they govern data and govern interoperability.
Karol:
And that already stems a lot of problems in agentic AI implementations.
Karol:
Because, of course, they want AI agents without the proper use case.
Karol:
But they want, because the hype cycle continues, they go on the bandwagon and they need it.
Karol:
And what it turns out, that we need domain partitioning.
Karol:
So, what do we need?
Karol:
Modularity.
Karol:
Again, it's quite interesting to observe that this is actually all the time the same thing.
Karol:
But then, again, if they apply modularity without reason, then we get lost again.
Vlad:
Yeah.
Vlad:
By the way, domain-driven design, I love domain-driven design.
Vlad:
But what is it?
Vlad:
That's a way to achieve modularity.
Karol:
Pretty much, yes.
Karol:
Because we're basically dissecting everything into separate boxes.
Karol:
Into pieces.
Vlad:
That's the problem with modularity, with that concept.
Vlad:
And it was problematic from the get-go.
Vlad:
Like, we need to divide a system into those components.
Vlad:
But how on earth do we do it?
Vlad:
Barbara Liskov said it many, many years ago.
Vlad:
She said, if you take a system and decompose it into components, arbitrarily what you will get is not modularity.
Vlad:
You will get a distributed monolith or a big ball of whatever.
Vlad:
You won't get good design.
Vlad:
You need good reasoning when you're decomposing a system into components.
Vlad:
And that reasoning, for me, at least, it was elusive until it kind of clicked and then the coupling book came along.
Vlad:
We have knowledge, we have distance.
Vlad:
That's it.
Vlad:
If we absolutely have to share knowledge, there is no way to avoid it.
Vlad:
We have to share lots of knowledge.
Vlad:
Things will change together, bring them close to each other.
Vlad:
That's what usually is called cohesion.
Vlad:
If, on the other hand, the knowledge that is being shared across boundaries of components is low, like they're not really related to each other, increase the distance.
Vlad:
They won't change together.
Vlad:
Put them in different components.
Vlad:
And yeah, so modularity is that relationship between distance and knowledge.
Vlad:
And its goal is to manage the cognitive load that you will have to experience when you will have to modify to change something in that system in the future.
Karol:
Now, I just wish right now that I had handy your deck from balancing coupling and software design the training on O'Reilly, because you have this absolutely wonderful slide about cohesion, coupling, and distance.
Karol:
You know, the four quadrants that you have?
Karol:
I can describe it.
Karol:
I remember it by heart.
Vlad:
Yeah, I know.
Vlad:
Go ahead.
Vlad:
In the middle of the night, yeah.
Vlad:
Let's take knowledge and distance.
Vlad:
And for the sake of this example, for the simplicity sake, let's say that we're treating them not as a spectrum, but as a binary value, high or low.
Vlad:
So, let's say we have two components that share lots of knowledge, but the distance is low.
Vlad:
So, knowledge high, distance low.
Vlad:
In that case, we have to look why they're sharing lots of knowledge.
Vlad:
If that's because of the business requirements, and there is no way to evaluate it, okay, that's fine.
Vlad:
We'll leave it.
Vlad:
Now, that relationship is what we call high cohesion.
Vlad:
Things that are related, close to each other, low distance.
Vlad:
On the other hand, let's say that the knowledge is low, and the distance is high.
Vlad:
Again, things that are not related, far apart from each other.
Vlad:
That's what we usually call loose coupling.
Vlad:
Now, the other two are all about complexity.
Vlad:
These two were about modularity.
Vlad:
The other two combinations are about complexity.
Vlad:
So, the first one, and the trivial one is, what if we have two components sharing lots of knowledge over large distance?
Vlad:
Guess what?
Vlad:
There will be pain in your future in that case.
Vlad:
You have to do something about it.
Vlad:
Either lower the knowledge, if that's possible, if not, the distance.
Vlad:
So, both are high, you get what we usually call tight coupling.
Vlad:
Now, the most, let's say, yes.
Karol:
Found it.
Vlad:
Yeah.
Vlad:
The trivial one is when both are low.
Vlad:
When you are not sharing lots of knowledge, so things are not going to co-evolve.
Vlad:
But on the other hand, the distance is low as well, so they're close to each other.
Vlad:
Now, if there are only two such components, who cares?
Vlad:
Now, if you have like a bit more, like let's say 10 such components, well, you are on your way towards like good old-fashioned mouth lathe or big ball of mud, because you have unrelated things in the same basket, pretty much like my room here.
Vlad:
If I would show you the stuff I have here.
Vlad:
So, you already have seen Terminator head and I have Formula One wheel over there.
Karol:
The same here.
Karol:
The view you have is the clean view.
Karol:
The rest of it is just pure chaos.
Karol:
Exactly.
Karol:
That's the one.
Karol:
I mean, rubber duckies all over the place or Lego blocks for modelling.
Karol:
There you go.
Karol:
You need to have a rubber ducky, right?
Vlad:
Yeah.
Karol:
Perfect.
Karol:
So, yeah.
Karol:
So, lots of modules close together with sharing of knowledge.
Karol:
We have a big ball of mud.
Karol:
They're just unrelated, just occupying the same space and it's a problem.
Karol:
That leads to confusion.
Vlad:
Yeah.
Vlad:
They will eventually, those two relationships, the complexity ones, when both are low or both are high, when you will have to change the system, it will increase the cognitive load.
Vlad:
You will have to look for things far apart that need to change or you will have to make your way through something like my room here, which is a hell of a cognitive load, if you ask me.
Vlad:
That's something that is not modular.
Karol:
And I believe the next slide is exactly on this.
Karol:
Low knowledge, high distance is modularity.
Karol:
Low distance, high knowledge is modularity.
Karol:
The rest of it is just pure complexity that doesn't serve anything.
Karol:
By the way, thank you, Philip, for bringing up cohesion in the comments because that's what sparked me into finding these slides.
Karol:
Definitely something worthwhile because this is what we're looking at in terms of coupling.
Karol:
Do we have actually modularity, which is great, or is it just complexity and it's added complexity that we don't need in this place and should be refactored and moved away somewhere so that we manage that complexity properly?
Karol:
Because I do like to quote, and I literally quoted that yesterday from Don Norman, the designer of Everyday Things, it's not the problem that we have complexity.
Karol:
Simplicity is something that we should really look out for and not have because simplicity is not there in real life.
Karol:
All the problem domains that we're touching, they're never simple.
Karol:
They're complexity.
Karol:
The problem is confusion, and we should look for managed complexity, and the managed complexity is something that we want.
Karol:
Otherwise, we just have complexity, and it creates confusion, so big bowl of mud, spaghetti architecture, these kind of things.
Karol:
All right.
Karol:
We're going to make a small pause in the topic right now.
Karol:
Vlad, did you have a moment to think about the question or what would we be doing right now in terms of the prompt that we had in our private chat?
Vlad:
Yeah.
Vlad:
I have no idea what question to ask.
Karol:
All right.
Karol:
Just to give you an idea, Vlad actually has vouchers for the digital version of balancing coupling in software design, and very generous, we have ten of them.
Karol:
So there's plenty to go around.
Karol:
Now, how should we distribute them amongst our viewers tonight?
Karol:
What do you think?
Karol:
Best dad joke?
Karol:
Yes!
Karol:
Yes!
Karol:
All right.
Karol:
So, dear audience, please, on YouTube, because YouTube we can actually showcase in the stream, because integration with LinkedIn comments failed today, ten best dad jokes we receive in the next 20 minutes, get a digital copy of balancing coupling in software design by Vlad Kononov.
Karol:
Three, two, one, start, and I see Philip is already trying to figure out a dad joke, but Philip, I believe you do have a copy already, or am I mistaken?
Karol:
We have a shared library of books in Bridging the Gap, and Philip has access to all those books, so yes, there's plenty of books there already.
Karol:
But let's give people a chance.
Karol:
All right.
Karol:
Going back to coupling.
Karol:
So, of course, we have, we talked about distance, we talked about the knowledge shared, which are two factors of coupling.
Karol:
Then we have a further access to the puzzle, right, because we're operating in coupling, at least in your model that you describe in the book, we have three axes, well, three characteristics that we need to look out in terms of coupling.
Karol:
So, the last one is volatility, right?
Vlad:
Yes, that's true.
Vlad:
So, the model that we discussed before the prizes section was kind of idealistic, like either something is modular or something is complex.
Vlad:
Either something reduces cognitive load or it increases cognitive load.
Vlad:
And the question is, let's say we have something that does increase cognitive load, but do we necessarily care about that?
Vlad:
Because again, if you look at domain-driven design, sometimes domain-driven design tells us we don't care, separate ways, we don't care.
Vlad:
From technical standpoint, domain-driven design says use those advanced patterns like aggregates, event sourcing, where it matters most in core subdomains.
Vlad:
Supporting subdomains, let cloud do its thing or outsource it or just some rapid application development framework, something quick and easy, something that will just work.
Vlad:
So, we have to introduce that healthy pragmatism into our decision-making.
Vlad:
And we can do it by looking at the source of shared knowledge.
Vlad:
Let's say that we have that relationship of both values are high, high strength, lots of knowledge and high distance travels across, let's say, systems or services.
Vlad:
Now, if we will have to change that upstream component, the source of knowledge, well, guess what?
Vlad:
Probably the downstream will change as well.
Vlad:
So, the question we can ask is, will it really change?
Vlad:
Because maybe that's a legacy system that nobody cares about.
Vlad:
Let's say that many organisations have that old legacy system that does its thing, people are afraid to touch it, but sometimes you need to integrate with it.
Vlad:
So, if it's not going to change, if it's not volatile, well, use some of its implementation details and use them for integration.
Vlad:
Go to its database directly and take whatever you can, because that schema is not going to change.
Vlad:
So, basically, that what we are doing right now is we're bending that ideal modularity thing and saying, okay, we don't need modularity in this place.
Vlad:
And it's all about volatility, because that part of the system is not expected to be volatile.
Vlad:
Now, legacy system is probably an extreme example.
Vlad:
If we go back to domain driven design, then we have those three subdomains, three types of subdomains.
Vlad:
Core, they will change the most.
Vlad:
You have to assume that high volatility there, and there is no other way around it.
Vlad:
Supporting subdomains, nobody cares about them.
Vlad:
They will change rarely.
Vlad:
And if they change, those changes are going to be not that dramatic.
Vlad:
Unless, of course, there's a big change in the organisation, and supporting subdomain morphs into a core subdomain.
Vlad:
Then you have to redesign everything.
Karol:
I have a caveat to that.
Vlad:
Yeah.
Karol:
Actually, one of the systems that changes the most in large IT ecosystems is the integration platform, and it's in the supporting subdomain most of the times.
Karol:
And integration platform has the most volatility, or interacts with the most volatility.
Karol:
And it's a supporting...
Vlad:
Can you give an example?
Vlad:
Yeah, that's an interesting case.
Vlad:
Okay.
Karol:
So, when I work on the integration platforms, and what we do, especially if we do API led architecture, which is three layers of abstractions, those layers of abstractions are there to support composability of services.
Karol:
So, we can compose new services, new business functions based on the exposed data in the adapter layer, and then the composition layer gives us that we can compose that data objects into services, whatever those services may be.
Karol:
Now, if I have the providers of data just behind the domain systems, just behind the adapter layer, whenever they change anything, the impact hits the integration platform, but not always hits the consumers of those services, because we just mitigate that impact of changes on the consumers, because we hide that impact within the adapter layer, the composition layer, and the channel layer.
Karol:
And different changes impact different layers of abstractions in the integration platform on its own, not necessarily impacting the end consumers.
Karol:
So, let's say we have five consumers consuming one service in the integration platform, and one of them needs more data in the response.
Karol:
So, we make changes on the provider systems, on the domain systems that are upstream.
Karol:
I'm never going to get used to the upstream downstream, but provider is upstream, right?
Vlad:
Yes, yes.
Karol:
Okay.
Karol:
In the upstream, we make changes on the upstream, that changes trickles through the adapter layer of the integration platform, the composition layer of the integration platform, and then is exposed in the channel layer only to that specific consumer, while the rest remain untouched, because we have that ACL in the channel layer that bars them from being impacted.
Karol:
So, actually, all the volatility of all the upstream systems is then squished into the integration platform and mitigated so that it doesn't reach downstream.
Karol:
That, I think, is an exception to a supporting domain being less volatile.
Vlad:
Thank you so much for saying that, because you naturally led me to the next topic I wanted to talk about.
Vlad:
Perfect.
Vlad:
Because volatility can be natural.
Vlad:
Yes.
Vlad:
So, the volatility that is caused by the business domain, and it can also be, let's say, inferred or accidental.
Vlad:
Now, let's say that you're a supporting subdomain, and you depend on a core subdomain, and that one, the source of the knowledge, is volatile, and its boundary is bad.
Vlad:
So, all those changes propagate across the boundary to the downstream, and that makes your supporting subdomain volatile as well, but not because of the nature of the business, but because of the design, because of the way that upstream doesn't care about its knowledge spilling outside of its boundary.
Vlad:
It basically introduces that situation we discussed earlier.
Vlad:
High knowledge, high distance.
Vlad:
That's exactly the case.
Vlad:
Yeah.
Karol:
Precisely.
Vlad:
Yeah.
Karol:
And at times, we take the integration platforms, and when that upstream system doesn't care about knowledge spilling, we put a barrier as the adapter layer, so that knowledge doesn't spill.
Karol:
So, we actually put all layers of the integration platform are essentially anti-corruption layers, and they have a different function in terms of anti-corruption that they serve.
Karol:
The channel layer barring the consumer systems for the knowledge of the integration platform spilling out to the consumers, the composition layer barring the knowledge about individual upstream systems spilling into the channel layer, and then the adapter layer hiding that whatever is the logic, the access logic, the data, the data models of the actual upstream systems.
Karol:
And this is exactly that cascading spill that we're just blocking with dams of abstractions.
Karol:
And of course, different integration platforms, different number of
Karol:
abstractions, because if we go to broker architecture, and there are integration platforms
Karol:
that are in that specific architectural style, they have a single layer of abstraction, and it's
Karol:
very hard to give more, and then the problem of solving coupling and problem of solving volatility
Karol:
becomes a little bit more trickier, still manageable.
Karol:
But again, it depends on what the company needs.
Vlad:
Yeah.
Vlad:
Again, I love that.
Vlad:
First of all, that's an example of a great implementation of anti-corruption layer, the domain-driven design pattern.
Vlad:
Second, it's a great illustration of the balanced coupling principles and what happens when they're broken.
Vlad:
It also explains how balanced coupling can help you to identify and guide you towards a solution, which is to introduce the integration contract, which is anti-corruption layer.
Vlad:
Love that example.
Vlad:
But I will just go back to the notion of subdomains.
Karol:
I'm not joking when I say that what you described in the book is like 50% of my work.
Karol:
It's true.
Karol:
It's just basically managing that coupling, managing that complexity, pure essence of it.
Vlad:
Yeah.
Karol:
Okay.
Karol:
Going back.
Vlad:
Yeah.
Vlad:
So what I meant by volatility of subdomains is the natural volatility, not the accidental one that can be caused by poor design.
Vlad:
With poor design, yeah.
Vlad:
If you implement a big ball of mud, then yeah, it doesn't matter.
Vlad:
If it's supporting generic core, it doesn't matter.
Vlad:
Everything will be volatile and everything will change together.
Karol:
That's very much true.
Karol:
Yeah.
Karol:
So if I look at system-to-system integrations, well, if we have point-to-point or even driven architecture, that usually is very hard to control that volatility.
Karol:
That's usually always high impact and a high degree of coupling.
Karol:
So we experience not only contract coupling, but also going into model coupling very often.
Karol:
But if we introduce integration platforms in between, that we can have that more refined control over that volatility and how it influences, impacts the other systems, meaning domain systems, because the integration platform itself is not a, well, not a domain system from a business perspective, right?
Karol:
It's a supporting system.
Karol:
As we already agreed upon.
Vlad:
Well, it depends.
Karol:
In some cases it can be core.
Karol:
Yeah.
Karol:
We already established that somewhere close to the beginning of the stream.
Karol:
Now, Philip is asking, have I shared the riddle for Eric Evans?
Karol:
And yes, we did talk about the riddle before the stream.
Karol:
Quite a nice story on its own about exactly integration platforms and the purpose of integration platforms in a sense of domain-driven design.
Karol:
But I think I told this story too many times over the stream that I'm not going to repeat it again.
Karol:
And we're still waiting for the dad jokes.
Karol:
There are still plenty of room in the comments for the dad jokes.
Karol:
I think we have about four now.
Karol:
So, if you do want to receive the book, then please do add the dad joke in.
Karol:
Okay.
Karol:
Where were we coupling-wise?
Karol:
Volatility, for the degree.
Karol:
What else can be?
Vlad:
Sorry, Carol, I'm just sharing here a quote that you reminded me about.
Vlad:
I'm sharing here in the private chat.
Vlad:
Yes.
Karol:
I'm going to put it in captions.
Karol:
Give me a second.
Karol:
There we go.
Karol:
Yes.
Karol:
So, any third-party system that I have to integrate with was written by a drunken monkey typing with his feet.
Karol:
Oh, my.
Karol:
I think you're hitting the absolute sense of my work at this point.
Karol:
The number of really badly composed APIs, definitions, behaviour of APIs that I've seen over the years really reflect this particular quote.
Karol:
Yes.
Karol:
You hit the spot.
Karol:
Nailed it on the head.
Karol:
Oh, dear.
Karol:
That's very true.
Karol:
Now, since we have our colleagues from SAP, somewhere in the chat, they were quite active.
Karol:
I don't know if you have ever worked with SAP R3, because now the current standard is SAP for HANA, which is a very nice, rounded system.
Karol:
But R3, the way older version of it, you couldn't integrate that without an SAP specialist present in the room.
Karol:
Because, yeah, that was definitely a job that secured you for life, in that sense.
Karol:
Because the interfaces of SAP R3, all the attributes were named as abbreviations of German words.
Karol:
They were not decipherable for anybody who was not in the SAP ecosystem.
Karol:
So, this is exactly the essence of the drunken monkey typing.
Karol:
Because you could not understand that.
Vlad:
That reminds me of MicroTik routers and their interfaces.
Karol:
MicroTik routers.
Karol:
Please tell me.
Karol:
I have no idea what that is.
Vlad:
Oh, so that's a router that some consider like a consumer device, but to configure it, you need a person that specialises in that thing, because its user interface is next level.
Vlad:
It's like Windows 3.11, Battleship Grey, and it's full of, like you said, those three-letter acronyms.
Vlad:
That thing works like, I don't know, like it's bulletproof.
Vlad:
You configure it once, and it will work forever.
Vlad:
It doesn't need no maintenance, but to configure it, wow.
Karol:
Yeah, that probably is quite an issue.
Karol:
And this is, again, literally, we're in the aspect of coupling, because that's the connaissance of meaning.
Karol:
We have the connaissance of name and type, where we already screwed up on the connaissance of name.
Karol:
We maybe not screwed up on the connaissance of type, because maybe the types are actually, let's say, well-defined in the contract.
Karol:
But then, if we screwed up on the connaissance of name, how can we even go into the connaissance of meaning, which is something that we actually very much need in the contract coupling, right?
Karol:
Because we want that contract coupling.
Karol:
This is something very much wanted, because we want to convey the contract that has a meaning, and we can use the shared meaning of data.
Karol:
And then, how can we even convey that, right?
Karol:
Again, landing in the coupling area.
Vlad:
Yeah.
Vlad:
Yeah, even with contract coupling, we can still make it hard to work with.
Vlad:
Again, from the modularity perspective, that interface won't reflect your implementation models, won't reflect your functionalities, implementation deals.
Vlad:
In fact, it can still be a very hard decipher.
Vlad:
So, we have connaissance of meaning, where you can communicate by exchanging magic numbers, for example.
Vlad:
That's one way a connaissance of algorithm can make things a bit more complicated.
Vlad:
There is a famous example from the original book about connaissance, when it was introduced.
Vlad:
Miller-Poe Jones used the example of a system that returned a sorted array of values and numbers for some endpoint, but because of the bug, the last two values were always in inverse order.
Vlad:
So, the consumers, when they received that, they had to do the same behaviour, the same algorithm, to take the last two numbers and reverse the order, and now they have a sorted array.
Vlad:
So, that algorithm was conveyed, and it could be conveyed across integration contract.
Vlad:
It still could be possible.
Karol:
Yeah, but we're adding...
Karol:
Well, it is a connaissance of algorithm, but then if they didn't know it through the contract, then basically we're looking more into the functional coupling, right?
Vlad:
Yes.
Vlad:
Well, yeah.
Karol:
Literally.
Vlad:
They figure that out.
Vlad:
But, yeah, that's an interesting point, because once they fix that bug in the upstream, that functionality has to change in the downstream as well.
Vlad:
Otherwise, guess what?
Vlad:
The integration won't work.
Vlad:
So, yeah, that's a very, very good point.
Vlad:
That's borderline functional coupling here.
Karol:
And they fixed the functional coupling, and then we back to contract coupling, but by fixing it, we introduced impact, change impact, into all the consumers, which is, again, heavy.
Karol:
And going back to my lovely example where I screwed up something by namespaces and exposing the model coupling to a consumer, and it took me four years to fix it.
Karol:
Yeah, we fixed it, but it took real effort and a really big project to incorporate those small fixes of those namespaces.
Karol:
The namespaces that was just one line in an XML.
Karol:
Well, XSD, precisely, but one line in an XSD that needed fixing.
Karol:
But because of that, we introduced a lot of brittleness, and it cost us four years of that contract brittleness to be able to really fix it, because we couldn't develop those services independently.
Karol:
They always have to be developed with all the consumers in line consuming the same services.
Karol:
That's horrendous.
Karol:
And then here we have a great example of even deeper form of coupling, which is functional, because the switch of the sorting.
Karol:
Oh, man.
Karol:
So now I hope everybody can now see how these really small things can really introduce very tight coupling, and that's why we do need those anti-corruption layers that really solve those problems.
Karol:
But what is an anti-corruption layer?
Karol:
It's just a layer of abstraction on top of that.
Karol:
What is the logic of that system, really?
Karol:
Or the open host service being that layer of abstraction on top of that.
Karol:
And to quote, again, quote attributed to Neil Ford here, nothing solves an abstraction layer problem like another abstraction layer, in that sense, because that's basically what it is.
Karol:
We have an abstraction layer of the system where we screw up something functionally, model-wise, whatever, and nothing can solve it like adding another abstraction layer like that ACL or OHS on top of it to fix it.
Karol:
That's where domain-driven design helps us with context mapping to just try to find out how we can balance those relationships so that they can work.
Karol:
And, of course, somebody consuming the OHS can conform to it, right?
Karol:
They can.
Karol:
Or they can have an ACL to mitigate those changes, because that's, again, we can couple tightly into that model of that published language and still have a problem, because we then have that coupling to that of that published language.
Karol:
And is that okay?
Karol:
Again, it depends.
Karol:
And we already explained that it depends on distance, volatility, and all those factors.
Karol:
And that's a difficult, I think that's, in general, a very difficult balancing act to be had, how to deal with that, right?
Vlad:
Yeah, that's why I think we are safe.
Vlad:
Like, Claude, I'm not afraid.
Vlad:
I'm still not afraid.
Vlad:
A few weeks ago, I had to look at a codebase that was written primarily by Claude, and we are safe.
Karol:
Yeah, and I've seen plenty of discussions on the topic, and why we're safe is because those models will return an average, or they will return a list of options.
Karol:
And who is going to decide which option is the good one?
Karol:
Because not that model, definitely.
Karol:
You require a human being, so you require an architect, somebody that actually understands the dynamics and all those dependencies on all those different abstraction levels, because it's not one abstraction level, it's multiple abstraction levels that we need to factor into that decision.
Vlad:
Yeah, and I like to define Majovari as design of a system that not only achieves the system's current goals, but also supports future goals.
Vlad:
Future goals that might be required from that system, like reasonable future changes.
Vlad:
The difference is, if you have a big ball of mud but it works, that works, but it's not modular.
Vlad:
Now, once you make it modular, then it not only works, it will serve the business in the future, serve the company, let it evolve in the future.
Vlad:
Now, what are those future goals?
Vlad:
Is it any kind of change?
Vlad:
No, that's not reasonable.
Vlad:
We cannot do a system, design a system that will allow all possible changes, like even turn a CRM system into, I don't know, a game or something.
Vlad:
We don't want to do it.
Vlad:
We want to focus on reasonable changes, like reasonable change vectors that are specific to that company, that period of time, that specific context.
Vlad:
And currently, the way I see it right now, that's something that we know.
Vlad:
And AI is, at the moment, too dangerous to trust with.
Vlad:
Then again, I don't know, five years ago, if you would tell me that I will have AI running, supporting subdomains for me, I wouldn't believe you.
Vlad:
So who knows what's going to happen in five years?
Karol:
Yeah, that's probably very, very non-deterministic what's going to happen.
Karol:
The AI industry tells us one thing.
Karol:
The reality tells us something completely different.
Karol:
The hopes and dreams of CIOs, CTOs, CEOs tells us another thing.
Karol:
And the complexity of what we're dealing in terms of coupling and designing architecture, building the right software for the job tells us, again, completely different things.
Karol:
And then we go to Barry O'Reilly, who will then tell us about residues, and that he's very happy that people are using AI, because that will give him a lot of work in the coming years as an architect, right?
Karol:
So, yeah, I think all of these are, to an extent, true, that these things will happen.
Karol:
But again, it depends.
Karol:
It depends on so many factors.
Karol:
Can they happen in these areas that we work in?
Karol:
It's ridiculous to even try to prognose that at this point, because it's just too little facts and too many hopes and dreams in that area.
Karol:
And I don't think that in terms of the level of complexity that we're seeing and we're tackling with balancing coupling, with integration architecture, with all those decisions that we make at a large scale, I don't think that this is a reality that these things will come to play in the next few years.
Karol:
I think this is still, they don't have the right sources to learn from.
Karol:
So, this is not even possible for them to even figure out, because that would mean they need reasoning capabilities.
Karol:
And we know that there is no reasoning capabilities.
Karol:
That's just statistical relevance at this point.
Karol:
So, we literally talked about that last week, just to make it clear.
Karol:
So, if somebody's interested in the ponderings on relevance of AI in development, that's last week's stream.
Karol:
You can watch it on YouTube.
Karol:
Just drop into that and rehash that, because that was the whole stream only about that.
Vlad:
Look, just to put things in proportion.
Vlad:
So, my hobby is making a laughing stack out of code written by AI.
Vlad:
At the same time, I'm not giving away my chatGPTN cloud licences, my subscription, sorry.
Vlad:
I'm not giving that away, because that thing made my life so much easier.
Karol:
Very much true.
Karol:
Same thing.
Karol:
I'm not giving away my Gemini subscriptions, because it just makes my life so much easier, if you know how to use it, right?
Vlad:
Yeah.
Vlad:
We just need to know what it depends on, where we can trust it will make the right call, or where we better work ourselves.
Karol:
Only always, in that sense.
Karol:
That's the part of the common sense of the DDD that DDD promotes.
Karol:
I think that's something that's quite important here, and this AI literacy at this point.
Karol:
But that is with everything.
Karol:
Microservices, we do need that microservice literacy as well, when to use microservices, how to compose those microservices.
Karol:
Should we do fine-grained or coarse-grained?
Karol:
That's that literacy that comes into play that is very much needed.
Karol:
Otherwise, we will not be able to do that.
Karol:
And AI will not help us in that kind of decision-making, because it doesn't have enough context.
Karol:
I hope not.
Karol:
I try to ponder upon that, how much context you need to build up
Karol:
for Gen AI, and I looked at the context I'm gathering as an architect to make architectural
Karol:
decisions, and just the sheer number of abstraction layers that I need to touch is overwhelming
Karol:
to put in an AI, because it's just those abstraction layers are so different,
Karol:
dependencies-wise, because we're looking at the business level of business requirements,
Karol:
business needs, business wants, then we look at translating that to business processes,
Karol:
that's another abstraction layer, then we're talking about translating that into architecture,
Karol:
that's another abstraction layer, then we're talking about translating that to
Karol:
development, to tests.
Karol:
We're just riding that elevator up and down all the time.
Karol:
If you put all those abstraction layers into LLMs or one AI agent, that's hallucination waiting to happen, rather than it being able to produce something, because this is just too much.
Vlad:
Today, what's going to happen in five years, in two years, I'm afraid to make predictions, to bet on something.
Karol:
I'm only betting on sustainability, because right now, if you look at OpenAI, they're losing money because of sustainability of the solutions.
Karol:
If you look at companies burning through tokens, again, sustainability of those solutions.
Karol:
In that sense, I think our knowledge about understanding, coupling, understanding those dependencies, being able to answer it depends, that's the crucial part, because we're more sustainable than those solutions.
Vlad:
Yeah, that's an interesting way to put it.
Vlad:
Yeah.
Karol:
This is the one reason I think that AI will definitely not replace us.
Karol:
All the other reasons are questionable.
Karol:
Unless we find an infinite power source, then we're good for the next few years.
Karol:
Here, we have exactly to the point, because I'm building a new PC right now, and this is my nightmare, that Stefan mentions.
Karol:
The cost of DDR5, DDR5 now costs as much as a good chipset, a good graphical chipset.
Karol:
I never figured five years ago that RAM would be so expensive, and that's exactly the point, right?
Karol:
That's exactly the problem in that sense.
Karol:
All right.
Karol:
We're still waiting for a few more dad jokes, so if you want the book, please do post a dad joke in the comments, because I don't think we hit 10 yet.
Karol:
Otherwise, we'll be, well, we've been at it for two hours.
Karol:
I believe we did not touch upon everything coupling-wise or everything DDD-wise.
Karol:
There's plenty more to talk about, but personally, my common cold is getting to me, so I'm dying here.
Karol:
I drank the whole jug, but it didn't help that much yet, and two hours is a lot of time.
Karol:
I know that you, Vlad, after four hours about talking about coupling, you're already dead yourself, so two hours is quite a lot, so last chance for anybody else to drop in a joke, and let's get into a few and unmark them with stars.
Karol:
Let's see what we got.
Karol:
So, Stefan, we have Sodium.
Karol:
Yeah, okay.
Karol:
Okay, good one.
Karol:
Yes, well, that's a meta-joke of dad jokes, I suppose.
Karol:
We have a very nice one tied to the theme of the domain-driven design.
Karol:
What do you think, Vlad?
Karol:
Yeah, good one.
Karol:
And continued, that they finish each other's stand-ups.
Karol:
Oh, man.
Karol:
Woo!
Karol:
That hits good.
Karol:
I think that's a good dad joke.
Karol:
How about you?
Vlad:
Yeah, that's like two jokes in one.
Karol:
Two jokes in one, definitely, yeah.
Karol:
That definitely deserves a book.
Karol:
Taking the it-depends architectural spin on romance.
Karol:
Okay, let's see if we have anything else there.
Karol:
Well, Philip, despite having a copy, I think he wants to go again for another one.
Karol:
I think Philip can gift the book to somebody in the SAP ecosystem for them to actually understand what coupling is.
Karol:
They have plenty of coupling there.
Karol:
Don't tell anybody.
Karol:
No, but we see when we use, that's the business model.
Karol:
When we use SAP systems, we understand how much coupling there is.
Karol:
Not everybody who buys SAP products understands how much coupling there is, and then they leave it for the techies to figure it out.
Karol:
And we do.
Vlad:
I meant the old implementation, the one with German words.
Karol:
I think there's plenty of couplings without the German abbreviations of words in the data model of, in the published language.
Karol:
There's plenty more to be had without that.
Karol:
So, that's still fine.
Karol:
Let's see.
Karol:
Do we have any other?
Karol:
Now we have only people laughing at the jokes.
Karol:
So, okay.
Vlad:
You know what, David, that asked the first question, let's add him to the list, because I love the question.
Karol:
Okay.
Karol:
We get David into the list.
Karol:
All right.
Karol:
We'll contact David as well.
Karol:
All right.
Karol:
Okay.
Karol:
Anything else that stands out that we can, anybody else that stands out that we can add to the list here?
Vlad:
Sorry, I couldn't keep track of all the messages.
Vlad:
When I was busy talking, you know, I'm single threaded.
Karol:
Fair enough.
Karol:
I mean, if I look at this comment, yes, that's a dead joke right here.
Karol:
That's the painful truth of our existence as architects and consultants, but at the same time, personally, I find it extremely funny.
Karol:
Because at a certain point in terms of stakeholder management, all we can do is just have a laugh about it, because it's not even a healthy kind of laugh, it's that panicked, cringy kind of laugh where we are just faced with the reality of things, and we cannot do anything more.
Karol:
All right.
Karol:
So, Toasty, you get a book.
Karol:
Let's see, you said David.
Karol:
All right.
Karol:
So, we're going to put David on the list.
Karol:
Do we have any more?
Karol:
Ah, right.
Karol:
We have a repost of a comment.
Karol:
I didn't realise that would be really a dead joke from my perspective.
Karol:
But maybe.
Karol:
Or maybe it just didn't hit me, but apparently it hits you very well.
Karol:
So, yes.
Karol:
Okay.
Karol:
Yeah, definitely.
Karol:
I missed that one.
Karol:
Thank you for reposting that.
Karol:
That's definitely something we need to put in.
Karol:
Fair enough.
Karol:
Let's see.
Karol:
So, all those people mentioned, you all get the book then.
Karol:
You all get the copy of Balancing Coupling in Software Design.
Karol:
Well, I think that some of them are really good.
Karol:
Especially this one.
Karol:
This one, you say, okay, long knowledge and distance, that's how my team works.
Karol:
That's not a bad joke per se.
Karol:
That's just the reality of things.
Vlad:
That's the best progressive level of champions.
Karol:
That's a fast track to a bowl of mud.
Karol:
Oh, we could go on and on in those.
Karol:
I don't want to bring the video from O'Reilly into it, but there was a lot more of those that you did as well, right?
Karol:
Oh, okay.
Karol:
Then Philip confirms that he'll send a voucher to somebody at the DDD community in SAP.
Karol:
I think that that will definitely help that community improve.
Karol:
And Philip is doing a great job at that, talking about DDD in the community, and it's getting a very, very nice traction in there, just to be fair.
Karol:
They're trying.
Karol:
They're building competencies.
Karol:
There's 40,000 people trying to learn DDD within SAP, and I think they're doing a really good job at getting traction of domain-driven design and understanding coupling within that.
Karol:
So, hopefully, we'll get better products.
Vlad:
Hi, Philip.
Vlad:
By the way, I know Philip.
Vlad:
I think- Yes, you do.
Vlad:
Did Europe, at least, and I think we had a few chats online.
Karol:
Well, precisely, DDD 22.
Karol:
There we go.
Karol:
And this is one of the reasons why Philip and I actually did a workshop at DDD 25, because you encouraged Philip to go out there.
Karol:
So, yes.
Vlad:
So happy to hear that.
Vlad:
Thanks for sharing.
Karol:
We might not know, but actually what we talk about really, at times, inspires people and changes people's approach to reality and sharing and building competencies.
Karol:
So, the more, the better.
Vlad:
Yeah, exactly.
Karol:
All right.
Karol:
I know we can talk for hours on the subject, and there's more coupling to discover, especially if we dig deep down into code, into modules, into relationships between different aspects of systems that we do.
Karol:
But I think that may be a topic for a different day than today.
Karol:
So, dear audience, and there's plenty of people still watching us, which is after two hours is not always the case.
Karol:
So, I'm really happy that there are so many people still watching.
Karol:
Thank you for joining us tonight, and before we all go, in a week, we're really continuing the problem of coupling, because we're going to be talking about tackling complexity with semantic metadata, and Marty, potentially, and he's a very nerdy and geeky guy, and I absolutely love the guy for it.
Karol:
He is now trying to write a piece of software based on his current code base that could be actually used as an analytical tool, and I encouraged him to do that, and he went for it.
Karol:
So, hopefully, he'll manage, because he had about two weeks for that, and a week has passed.
Karol:
So, that's going to be interesting if he manages.
Karol:
If he doesn't, we're still going to have an absolutely amazing session about semantic metadata, because that's his bread and butter in the integration world, and he already has some interesting insights.
Karol:
Now, of course, if you want to learn more about what we do at Bridging the Gap, visit the site.
Karol:
You can also see all the upcoming events by scanning the QR code visible to the left.
Karol:
Philip and I were running also a very nice training at DDD Academy this year, so we're talking about how to utilise DDD strategic and tactical patterns to design interoperability between systems, which is basically what we talked about today as well.
Karol:
Well, not the design part, but at least the understanding the dependencies part.
Karol:
And then, of course, if you're new to Bridging the Gap, and the loosely coupled live streams, please do subscribe to the live stream, to the channel on YouTube, and there's a QR for that.
Karol:
So, Vlad, I suppose how we're going to do that, just to let people know, please, I think everybody ping me the emails on my LinkedIn, in a private message.
Karol:
If you don't have me on LinkedIn, please add me on LinkedIn.
Karol:
I'm really easily findable, and then I will relay all those email addresses of the winners to Vlad to distribute the codes for the book.
Karol:
Does that sound reasonable?
Karol:
Yeah, perfect.
Karol:
Fantastic.
Karol:
That said, everybody, thank you for the amazing comment section tonight.
Karol:
That was absolutely great.
Karol:
Vlad, thank you for joining us for this session.
Karol:
Absolutely wonderful to have you here.
Karol:
Hopefully, not the last time.
Vlad:
Thank you so much for having me.
Vlad:
That was an amazing conversation.
Vlad:
I really loved it, and, yeah, I hope that's not the last time.
Karol:
Awesome.
Karol:
We'll find a more specific deep dive topic for the next time, just to have more fun in nuances.
Karol:
All right.
Karol:
Fantastic.
Karol:
So, thank you, everybody.
Karol:
Have a great evening, afternoon, and, well, wherever you are, or maybe a morning.
Karol:
I don't know.