Coding Blocks - Software Architecture – Strategic Design and Domain Events
Episode Date: June 26, 2017We're not saying that Michael is Carmen Sandiego. We're just saying that nobody has ever seen them in a room together. And this week, we don't know where in the world either are, as Allen and Joe cont...inue the Domain Driven Design discussion without Michael. Nor Carmen.
Transcript
Discussion (0)
you're listening to coding blocks episode 62 subscribe to us on leave us a review on itunes
stitcher and more using your favorite podcast app visit us at codingbox.net where you can find
show notes examples discussion and more send your feedback questions and rants to comments
at codingblocks.net follow us on twitter at coding blocks or head to www.codingblocks.net
and find all our social links there at the top of the page.
With that, I'm Alan Underwood.
I'm Joe Zach.
And Outlaw's enjoying the good life somewhere.
He's on vacation this weekend.
We're pounding ahead.
The show must go on.
That's right.
This episode is sponsored by FreshBooks.
The all-new FreshBooks makes ridiculously easy accounting software that's transformed how freelancers and small business owners deal with their day-to-day paperwork.
It's been redesigned from the ground up and custom built for exactly the way you work.
FreshBooks provides the simplest way to be more productive, organized, and more importantly,
get paid quickly. Getting started on FreshBooks is extremely simple, even if you're not a numbers person,
especially if you're not a numbers person. Now, when you email a client an invoice,
FreshBooks can show you whether they've seen it. This puts an end to the guessing games.
The new notification center is like your personal assistant, letting you know what's changed in your
business since you last logged in and what should be dealt with, like overdue invoices.
This lets you focus on what's needed to get done and to help you get back to work faster.
FreshBooks is offering a 30-day unrestricted free trial to our listeners. To claim it,
just go to freshbooks.com slash coding, C-O-D-I-N-G, and enter coding blocks in the How Did You hear about us section okay and with that let's
go ahead and get into our news section and first as we always do we want to thank our reviewers
so these are one of these is kind of interesting you are ir smitty abe chrissy and j1191919
yep yours are a little more difficult than mine.
I've got the stitch reviews this time.
So big thanks to Cleveland and Nate,
the DBA.
Awesome.
And as always,
uh,
visit the website for the full show notes.
You can find it at cutting blocks.net slash episode 62.
Excellent.
All right.
So I was reading the other night,
you know,
just trying to get more involved with this domain driven design thing.
And one thing that has bugged me about this whole thing is, is persistence models.
We hear about these things called bags of properties, right?
And it's really, when you see a class, it's nothing more than a bunch of public properties
with getters and setters on them, right?
It bugs me.
Like I look at that and I see that everywhere in code, like all over the place,
everywhere I've ever worked, you know, those things seem to just be, that's just how people
do things. Right. And typically that's like your DTOs. And one of the things that we're looking at
in the domain driven design stuff was this whole thing of really, you should not have an anemic
domain models because that means
that you're basically just creating these bags of getters and setters. And so I was like, well,
you know, how are people doing these differently? And I found this great article that I tweeted
about, that this guy talks about the persistence model, which is basically your kind of like your DTO versus domain model, or how you can kind of
get to that without having a wholesale change your entire app. And so there were a few key takeaways
from this that I thought were important to bring out just so you can think of, hey, you can't take
your entire application and maybe convert it to domain driven design. But there are some practices
that you could put in place
that might ease some of your pains that you're already feeling.
So Joe, you and I dealt with this at a previous company
where basically we abused the heck out of entity framework, right?
And so essentially our persistence model,
which were the things that mapped to the ORM,
everything started getting
crammed into those things right and and all the all the properties on those classes were were
public get set type things and so you got into this thing where you're constantly trying to
maintain the state of this object right like if there was a tax thing on order line item then it
just became a nightmare trying to figure out how do I get this thing back into the proper state, right?
One of the things that this guy said that I really liked is the very first thing you could do is in your persistence model, get rid of all these sets.
Make everything a public get and a private set. And what that would indicate is you were sort of
moving to this behavioral type thing. So if you're going to not create another layer, you're going to
stick with just your persistence layer and you're not going to create a domain layer.
You get rid of all these things where people can just go in and willy nilly change a property on a
class. Instead of doing that, you now create
methods or maybe even an interface to it so that you expose public methods that can be operated on
and those maintain the property changes within the class, right? Yeah. So, go ahead. I was just
thinking like an example might be instead of saying my object dot status ID equals four,
you might do something like my object dot disable.
And it may in the background just set the status ID equal to four,
but it may also insert a history record or do a soft delete or hard delete, do something else.
That's absolutely what he was getting at was just that.
You don't have to have this intimate knowledge of all these
little pieces, right? Your, your behavior method will. So I thought that was excellent, right?
The second way that they said about doing it, um, that was actually, that was actually a second one.
The first one was just leave everything the way it is. And that, that kind of stinks. The second
way was adding in the, the private setters,
which I think, I think buys you a lot, especially if you don't have a super complicated domain.
I think that's a good way to go. The third way is you have a separate domain,
but instead of trying to do a full on mapping, you sort of kind of mix the two, right?
You leverage the, the persistence layer
in your domain essentially is what it boils down to because what he goes to in his, in his ideal
world is you just create a domain and you don't even have a persistence layer, which is kind of
interesting. I don't know if I fully followed that. It would
definitely make your business logic a lot cleaner, but then some of your translation stuff would be
a little bit more difficult. And, you know, coincidentally, we're going to be talking about
the anti-corruption layer in this particular episode. So I think it kind of falls in fairly
nicely there. But yeah, I think it's important to know that this doesn't have to be an all or nothing type of thing, right?
Like you could take some of these ideas and say, oh, okay, instead of just operating on these objects, just like there are things that I can toggle switches on, think about the behavior that those objects can do.
Write application methods that way, and then those are responsible for doing things. And that also
has a side benefit of also making things more testable, right? Because now you have one thing
that says, Hey, if I, if I call this behavior, then it should have mutated the state of these
things over here. And you can at least anticipate that the output of that is consistent. Yeah. I
really like the sound of that. And it's a nice experiment that you can give a shot. And if you
find that you're having a lot of pain points when you try to do that then maybe that's a sign
that you have something else to think about you know maybe you're doing something wrong or you
know maybe maybe ddd isn't for you I don't know yeah very true I I guess that's one of the things
is I really like a lot of what what we're going through with this ddd the only problem that I
really have up to this point is the number of layers that you could potentially have, right? Like this is definitely for
complicated business situations. Yeah, it's not worth bringing on the vocabulary alone if you're
doing a small project. Right. And I think that's really the big thing. But there are a lot of
fundamental ideas in here that I really like. That whole idea
of focus on the behavior, right? Because as object-oriented developers, a lot of times I
think we get hung up on the thing that, hey, we have this object and we can change these properties
on this object. That's really not how we should be thinking. We should be thinking, what are we
trying to accomplish, right? And now let's encapsulate that behavior and now we can at
least guarantee certain things
right so yeah it's funny like when i do work for work uh i tend to think very data centric like i
think about the persistence layer first and foremost but um pretty much any side project i
do there's like rarely a database involved like i'm usually doing some sort of video game or some
you know some little fun thing whatever so I kind of have to think behaviorally,
but it's weird to me to kind of have one foot in two different domains.
But that might actually help, right? And maybe that's something that we put together some sort of thing on GitHub. I've been trying to think about how we could do this and I don't want to
nail us down to something because we've all got too many things going on, but it would be interesting
to take that and just look at, hey, what would a baby step towards this be, right?
Like take just your standard app that you see out there with these bags of properties and step it towards something that's a little bit cleaner.
It'd be cool to see like multiple takes on the same kind of project.
Like if there's like a well-defined, like this is how you, what you have to do and just see the different ways people solve. Take a DDD approach or take a data-centric approach.
Yeah, and the thing is, like you said before, you reached out to Eric Evans, and he was like,
yeah, I don't really know of any open-source projects because it's just not one of those things that lends itself well to the open-source community on that.
Anyways, that's all I had on that.
I thought it was interesting
and hopefully it ties into this show a little bit later on and i did finally get the comparison
review out of the lenovo yoga 720 versus the hp spectre x360 the youtube video is live as of 2 a.m
last night so please do go over there check it out hopefully you enjoy it if you
do leave it a thumbs up subscribe to our channel we're going to maybe do some more hardware reviews
and and we'll definitely be doing more coding stuff yeah excellent i actually haven't watched
yet but i'm looking forward to it but um i also uh we ran a contest recently and asked people to
send in their favorite manufacturer and i've actually got the results up here um uh i think maybe we'll send it out in the next email blast too but
you care to take a guess at what the number one uh chosen laptop manufacturer was
it's either going to be apple or dell i
i'm gonna go with dell all right So Dell was actually number two with 16%.
Apple is number one with 32%.
Wow.
That's double.
That's impressive.
Number three, Lenovo or HP?
Man, you're good at this.
Number three was Lenovo.
HP was down at number seven, actually.
Well, wait a second.
Who would number four would be I
don't even know who I'd go with at number
who would that be? Asus
but they were also they were tied with Microsoft
actually which I thought was really surprising
that people kept talking about the Surface
I mean the Surface
is a killer device and the Surface
book is too if you got the cash on you
yeah and there are actually a couple I'd never heard Surface Book is, too, if you've got the cash on you.
Yeah.
And there are actually a couple I'd never heard of before, like MSI, Razer, System76, and a couple other, literally others.
Dude, you haven't heard of Razer or MSI?
I probably couldn't name three main manufacturers.
I'm just not a hardware person.
Dude, come on, man. By the way, the Razer makes one called the Razer Blade called the razor blade stealth man that is a beautiful machine i think it's a 14 inch it's got a gaming
video card in it like rgb colored keyboard it's amazing anyways all right so if you got 2k to
spend and you want something super high end that's one yeah yeah and we'll have this little graph
and these numbers in the show notes as well as well as a link to the video that alan posted excellent all right so uh now it's time to go
ahead and get on into the show and joe's going to kick this section off because again we sort of did
the same thing that we did last time and some of us took certain sections and so some of us will
be naive all right so yeah start startup um i kind of took the
chapter in the book on strategic design um which is just more focusing on where we put stuff which
i i think has been kind of the driving uh force between all of this whole book and this whole
notion of dvd is just where i put my stuff and i think that's actually um probably the biggest area
that i struggle with like much more so than like actually um probably the biggest area that I struggle with
like much more so than like a lot of the micro stuff that we've talked about we've mentioned
this before too which is um to me this is the stuff that um I constantly make mistakes on or
second guess or you know um see later and these are the things that a lot of times like when you
come back to your code six months later it's so much clearer what you should have done and you
know I'm still kind of struggling with why did I know have done. And, you know, I, I'm still
kind of struggling with why did I know that at the time? And, you know, am I wrong now? Was I
wrong then? I, I don't know, but, um, it was just some kind of guiding principles for thinking about
things at a high level, a very large organizational level and, um, you know, even architectural.
And so, um, we've got a couple of strategies here for how to kind of deal with, um,
these kinds of larger level concepts.
And so we'll dive into that.
But first, I thought there's a pretty cool allegory here.
If you think about a large organization, we'll just say Amazon, their end goal, like if they could have a little magic wand or something and they had one wish, they might ask for a single system to do everything.
It's completely tightly tuned and integrated to do everything for their entire business.
So you can kind of imagine how absurd that is to think about maybe using Amazon.com for the
entire business and having it be one application with single sign on and upgraded all at once. It's
kind of ridiculous to think about it, but I could think, I can see how that could be a good goal.
You know, everyone's been frustrated, at least the business users with them logging into the
personnel website and then the ad administrative portal for the website, then going to see how
things look to the customers,
and then logging in somewhere else to check their email. And we use all these various tools. And so
there's a lot of overhead and a lot of switching around with that. And we lose a lot of stuff
because there is no integration. So you can imagine if your company kind of controlled
all communication, which is a bit scary, but you can imagine, you
know, the, the power, uh, that might be had if say, uh, your email was completely integrated with
your system. Right. And you could do things like respond to emails and make things happen. And,
um, you know, we're waving that magic wand there, but it's just kind of, um,
defining a goal for like our perfect world state here and since that is pretty much uh ridiculous and never going to happen for any sort of
company of any size even uh you'd be you'd be it's just absurd it's not even worth thinking about
but um the idea here is to contrast in in in terms of uh real world right so what we do is we try to figure out
how to modulize parts maybe we take amazon.com and we split it up and and we have the admin portal
we have the customer website we have that you know the payroll website whatever and we include
third-party things like you know email or microsoft word or you know whatever we use all these various
tools where they make sense because it just isn't worth writing software and trying to integrate that because we'll just never get done.
So what we're trying to do now is trying to figure out how to modulize things in such a way
that it does make sense and that we do get the benefits of integration without losing more in
the process of having to build and maintain this stuff so we're
trying to figure out where to draw those lines and trying to find those lines um that makes sense
between a monolithic app and so many um kind of small microservices that's just uh um i guess
kind of a mosquito swarm right that's kind of the opposite system you imagine you have like one
little tool that does one little thing it It basically imagine your, uh, you know, your, uh, marketing department
trying to, to use like Linux, literally, you know, no UI bash all day long to do all the work,
email via pine, whatever. So that's kind of the opposite end of the spectrum there.
So, um, they give us three guiding principles.
And we're going to be focusing on one of these today.
I'm just going to mention the other two.
The first is context.
And that's the one that I'm going to be talking about the most tonight.
And that basically deals with where we draw those lines, how we draw them,
how do we keep them separate, and how do we keep them clean.
The other two are distillation and large scale structure, which really just kind of build on context a little bit and talk about kind of keeping that context pure and how to how to grow things a little bit bigger.
So we'll save that for another time.
But first.
I want to talk a little bit about model integrity and the kind of the guiding principle
behind these contexts and keeping things split up is that we want to maintain model integrity
but like those that's a pretty abstract term right like what what is what does uh model
integrity mean to you alan i would think seeing as how we've already talked about it in the past
that it's got to do with the invariance right making sure that the state of the object
is always good right like it can never be in a bad state so i think that's i think that's what
they'd mean by this.
Yeah, and that's pretty much what they say.
But have you ever gotten a ticket that said you need to clean up some model integrity?
Yeah, that's not using the ubiquitous language, is it?
Right.
So what is the ubiquitous language?
How can we, what do they really mean here?
I would say that, I mean, if you're talking
about your particular domain, you're going to say something like, uh, if you're talking about
an order system, right. And, and somebody places an order for an item, you're never going to
allocate inventory that you didn't get paid for at the same time. Right? Like it's a rule like that, making sure that there is a transaction that says these either
all end up getting flipped or they don't, right?
That I think that's what they're getting at.
Yeah.
So that's definitely an example of integrity.
It's kind of persistence integrity, right?
And so I'm trying to kind of take that and move that a little bit more general, right?
As soon as I hear the word integrity, I think about database.
I think about atomic interactions.
I think about things like foreign keys, stuff like that that kind of enforce integrity,
but what does it mean to have code integrity or model integrity?
And so reading in the book, it kind of gives a couple examples
where you can think about
different teams of programmers kind of taking the same rules and the same notions and having
slightly different interpretations, maybe kind of skewed by their own biases based on
whatever they're building.
But taking that and kind of inventing their own code to deal with the same types of problems
and then those things kind of mismatching with the kind of stuff that maybe my team is doing.
And so what we're saying here is that integrity is a measure of how similar these conceptual models are and therefore how similar the code is.
So one example I like to hear is that you can imagine that a programmer got a ticket to allow a customer to
delete their information. And so maybe this programmer A went in and they added a new status
and maybe they created a history and a record table to show that the person was deleted,
the customers deleted, and that they were logged appropriately when the person who maybe initiated the action got the add-up
and then we call it a few years later,
program B has a task to remove customers
based on some sort of batch process.
Maybe they got a spreadsheet of customers
who complained to the Better Bureau of Business or whatever
and so we want to delete them out of the system.
And so they might just do a little loop there and literally just um update the column but not know about the history
and so now we've got some maybe reports that are going to be having some fishy numbers or
maybe some other stuff you can imagine a couple years later you know the other another way of
solving the problem would maybe be to just delete the records. And if you don't have that behavior kind of solidified,
then they might just delete the rows and the history table is going to be screwed
because it doesn't have that foreign key there.
But in this example, like using a database,
you can use things like foreign keys and triggers to enforce that integrity.
But I don't really know how to do that in code.
This is something that I think all of us have struggled with, right?
You go to do something and you do your best to find if it already exists somewhere,
but how do you find it?
How did somebody else name it?
Do coding standards, would they have fixed that problem i mean you know there's there's too many variables that come into play when something like that
exists and if you don't have some sort of layer or library that's set up to handle that kind of
behavior that people know to go to then i don't know how you enforce it especially when you have
you know dozens of
programmers or hundreds of programmers in some situations or 18 000 or you know however many
microsoft's got or google right yeah it just gets out of control and even you can imagine a small
team like um say i go out and i write some little email utility that logs and grabs the settings
from here and there and it sends an email someone else comes along and they've got just some little
task and they just do a system.sendmail type thing.
Now they may have skirted any sort of issues I may have had about,
say, whitelisting or preventing certain users from getting emails
or maybe thresholding sending emails too often.
This person didn't know about that stuff.
They didn't know about the code I wrote.
Maybe they're not even in the same bounded context,
meaning the same, in this case, the same application.
Maybe they're writing a little executable that kind of stands alone
or maybe a different application or website entirely.
And now they're kind of skirting the rules that I set up.
I may not know that they're skirting the rules.
And so we've got an integrity problem, right?
We've got a problem with model integrity.
Are you talking to me?
Did I write some sort of utility recently that skirted your white list?
No,
no,
um,
totally,
totally metaphorical,
uh,
not metaphorical,
anyway,
hypothetical.
Um,
and,
uh,
so,
you know,
even if it wasn't 100% feasible a company a company to uh or a large
organization to enforce that uh it may not even be worth it and uh that's one thing that i kind
of got i thought was really cool in the chapter um and we'll come we'll touch back on that in a
little bit but um the amount of complexity sometimes that it takes to enforce perfect
integrity across any sort of large system
um it's it's no joke and so sometimes you got to be a little you know pragmatic and take anything
we say with a a grain of salt i'm certainly i'm always uh uh you know eating a lot of salt i guess
but uh they did give us um this is kind of an aside in the chapter,
but I thought it was pretty interesting anyway.
They give us four rules or four risks for overambitious unification.
And I like to call this like the new system syndrome.
When you start working on something new that's supposed to replace you know one two three
old systems and every time there's a problem uh while this is being worked on someone says oh
we'll fix it in a new system we'll fix it in a new system or this is going to be totally different
new system and you know next you know two years later the new system still hasn't shifted still
done it's got all sorts of switch problems. But they actually identify four factors that lead to that.
And so I thought that these are like four things
that you could consider
when you're thinking about doing a rewrite.
And one is too many legacy replacements attempted at once.
That's so huge.
Yeah, and I think about it
as just kind of keeping the scope small.
Like rather than trying to replace your entire business with a flip of ones in which like maybe kind of break it
off into little chunks and deal with it in pieces.
Well, dude, we've talked about this in the past, right?
It may not even be multiple systems.
It could even be just one system that has so much complexity in it that, you know, to say, hey, we're going to replace this system is
naive, usually at best, because the amount of time and effort it takes to just reverse engineer and
pull out all the business logic, right, for your operation to run smoothly, it's nearly impossible.
So it makes a lot more sense to, if you're going to do anything, phase out a piece at a time, right?
A very small domain that you can iterate on.
Yep.
And oftentimes a larger project will actually bog down just because the coordination exceeds the abilities.
And the abilities don't necessarily mean the skill, but also just, you know, the headcount.
Like people have other stuff, they have lives, and they have other obligations that they need to do.
And so it just may not be worth it um the coordination may it just may not be possible um
also uh there are applications with specialized requirements and so um you may have to cheat some
rules and you'll see this sometimes like when um there's some interesting quirks in the old system
that you thought were bugs, but actually had some good
side effects.
I'm sure everyone's dealt with that.
It was a feature.
Exactly.
It's like you comment out that piece of crap code
and all of a sudden everyone's getting their orders
for free.
The last one I had here
was additional
complexity required to do
everything may not be
worth the gain. An example like there is you've probably seen in accounting packages or maybe
marketing or something where they'll do 80% of their job in one system and they'll flip to the
old system to do something old. I'm sure everyone's had a customer service experience like this where
they dealt with somebody on the phone and like, hold on, let me check the old system.
And sometimes it's just worth it to keep that around, at least while transitioning.
And sometimes even forever, you know, if you've got a good 80-20 rule where you can solve 80% of your use case with, you know, a fraction of the effort it would take to get to 100, then, you know, maybe that's a pragmatic compromise.
Yep.
So what do we need to do?
The idea behind this whole chapter is basically to consciously decide on strategies
and then be consistent about enforcing them.
And what we kind of said before is you can't 100% guarantee this integrity, right?
We don't have foreign keys we can put on programmers' keyboards.
We don't have triggers.
We do have some tools, but they're not great.
And so we want to start by taking inventory of what we got
and mapping our bounded context.
And then we've got a couple strategies we're going to lay out here
for trying dismally to keep our modeling
integrity up.
We said bounded context a couple times, but I haven't really defined it.
It's kind of hard to define it.
Sorry about the ums. Man, I'm driving myself crazy, guys.
I apologize. Without outlaw here to keep me straight, I'm just
umming around.
But the idea behind a bounded context
is to draw a line around some related functionality. And it can actually mean
a lot of different things. But for me, the easiest way to conceptualize it is to start with
an application. You might have that customer-facing website.
You might have that admin.
Those could count as two different bounded contexts.
And things like the schema of the database go along with that.
And so it's not just an area of code.
It's not just a namespace.
It can be an area of code.
It can be a namespace.
It can be a library.
But high level, the easiest way to think about it is to start with the application, I think. So tell me this, how does that relate to your aggregates
and your aggregate roots? Because it sounds like they're sort of similar, right? Because your
aggregate root encompasses this entity. Well, I guess that'd be the thing, right? Because your aggregate root encompasses this entity.
Well, I guess that'd be the thing, right?
Your bounded context would be around a number of aggregate roots at this point, right?
Like that's your higher level abstraction, your grouping of your domain.
Right.
And the aggregate roots specifically specify that all input kind of comes in through the root and then gets disseminated.
And this isn't about that so much.
You basically draw a big circle around things that kind of make up a part.
And I want to stay away from the word module because that's got some other connotations and languages.
But some other examples might be like a command line interface.
If you're like Amazon Web Services, you might have a set of web services that people can use to call to set up virtual machines, whatever. But you may also have, you know, a little bash library or a PowerShell component or something that makes that easier.
You've also got the website where people can control.
You've got the web services.
So there's a lot of different options.
And each of those might be considered different bounded contexts because they each have borders.
And one example that the book gave that was really good was a cell in your body, right?
They've got vacuoles, they've got DNA, they've got RNA, they've got all these little pieces and
there's a lot in common between them, but they also have these membranes or cell walls around
them that control the inputs and outputs. And so those are great examples of bounded contexts
because they have hard boundaries between them.
And sometimes the boundaries in code aren't necessarily as clear.
And that's something we need to work on.
And so the book actually, I thought it was kind of interesting.
A lot of the advice they give in this section is actually um managerial or um project
managerial as well as uh code related which i thought was pretty interesting because uh it's
not just important to have um your code divided up into these bound contexts but you also want to
kind of organize your development teams around it like you don't want um people working kind of helter skelter all over the place because that
um makes it harder to maintain that that integrity in the model and it goes just because it makes it
easier to for people to do things like the examples we've had before like reinvent something
because they don't realize that there's already an established pattern for it. So how do you define these
bounded or how do you talk between bounded contexts? If you've got something like that,
what are you doing so that if you have, I guess in our order system, you have orders,
you have customer service and you have accounting, right? So if something comes through customer service and they say, oh, the customer's unhappy, let's refund it. And then
they, in their bounded context for customer service, say, hey, we're going to refund this
order. That's now going to have to head over to an accounting bounded context more than likely,
right? If those are two different department apps that are being worked on yep how how does that
inner or outer bound bounded context work sure and what we have there are translation layers
and there's a couple of um a couple types of translation layers that we're going to be talking
about but basically the idea is just that you're going to have um some interfaces that you can call
and so interfaces that can be called uh from you
and those are things that you're going to set up to facilitate this two-way communication so
as in my customer service bounded context i'm going to have a call somewhere there that says
you know cancel order or something and it's responsible for translating that message into something that can communicate with an accounting
service. Okay, so let me let me draw this picture a little bit out of what I have in my head right
now. So last episode, we talked about aggregate routes, aggregates, and various entities and,
you know, objects that flow down through there, right? So at the very top was the aggregate route
and anything that needed to happen to anything that it's surrounded had to go through that,
right? And then it could work down in there. It sounds like this bounded context is now the
layer on top of that. So that is kind of drawing the box around these, these bounded context. So
you're talking about having an interface, like a true coded interface to saying, at this bounded context, you can place an order, right?
And so if you want to place an order, it's going to call the bounded context place order thing.
Then it's going to go down to the aggregate route that it knows to reach out to
and do something there. Is that what we're talking about? Like if we're peeling the
layers of the onion here right now, currently the bounded context is on the outside,
aggregate routes are the next level in and then so on down. Does that sound right?
Right. Yeah. If you want to interact with my domain service and I want you to call some sort
of web service or I want you to put a file in a folder or something on a queue that i you know i can be pulling for
i don't want your service mucking around in my database and that happens you know realistically
we're going to be sharing data we're going to be sharing databases and whatnot but ideally those
behaviors are going to drive those changes rather than
just changing the state on us willy nilly.
That's, that's interesting. You know, it's funny, it just as an aside here, because I'll forget this in a minute. My entire career, like I've pretty much always had access to
databases, right? No matter what it was, whether it was an ordering system or some sort of
analytic stuff we were doing, whatever, I almost always had access to the underlying data. And so
what you said earlier about batch processing, you know, something went wrong in the system. Oh,
let's just go update all the tables. The more, the further I've come in my career, the less I like
having access to that stuff.
For the very reason that you're talking about with the integrity, right?
Because it's too easy to miss something.
Unless you have just crazy intimate knowledge about the entire system, you're going to miss it.
And you still lose things like you mentioned earlier with the logging.
If you did need to batch update,
oh man, all these customer orders didn't get processed, right? And you knew the tables where
you needed to flip all those switches. You can go set all those bits, but now you lost your entire
audit trail, right? The more that I think about this stuff and the more that I've worked in systems
over time, the more I feel like somebody does need, I mean, somebody's got to be
writing that persistence layer, right? So I'm not saying that you don't have access to the database.
I'm saying that you should never actually be writing any kind of processes directly on the
data. You should be flowing through the business logic that somebody has already written in your
application. And it's so important because there's so many minute little things that you'll miss and you can't recover.
Yeah, absolutely. And if that's not an option,
and realistically sometimes it's not if the issue is important enough
for the problem bad enough, ideally you're going to want to get someone who's
close to the problem, someone who really knows that bounded context
really well, like a
developer who maybe wrote it and minimize your chance of error. But still, the risk is too high,
right? Like it almost makes sense to somehow wrap that bounded context or whatever that code is,
write your executable that way, right? Don't write some update statements against the database
because unless every single piece of logic logging audit trail
everything can be done from the database which a lot of times can't then you're going to miss
something yeah absolutely but i mean there's times when like the website's crashing because
there's a cycle and a category or something and like you know you're not gonna start writing uh
writing some web services so that you can tackle that, right? You're going to fix it as soon as possible.
Yep, totally.
I mean, it's not a one-shoe-fits-all or one-size-fits-all.
I mean, it's definitely something, though,
that I feel like more people should think about is, you know,
if I do have a problem, then maybe I need to improve my model.
And then that way, when I improve my model,
then this problem goes away.
You start reducing the one-offs and the hacks.
But anyways, go ahead.
Yeah, especially when those one-offs become two-off, three-off, four-offs.
That's usually what happens, right?
It's never a one-off.
And you start writing scripts to do your one-offs.
Automating your one-offs. Yeah.
So two types of problems uh occur in these bonded bonding
contexts that are common um one is duplicate contact duplicate concepts which are when two
entities represent the same concept and uh concept is an interesting word here because it can mean
like the same entity like the same table but it can also mean the same type of behavior like you've
got two buttons that do things similarly and you kind of copy and paste that behavior in two different places. Now they
want to do, you know, add a privilege or something around that button. Well, now you've got two
places that you need to maintain. And hopefully you remember because there's, you know, we don't
have those kinds of referential integrity locks like we do on a database. And so, you know, it's
up to you, the coder to know, to do that and then to execute it properly.
And if that fails, maybe, you know, a code reviewer.
Otherwise, your customer is going to find that bug for you.
The other is what they call false cognates, which is like that word cognates.
Like, come on.
I mean, come on.
There's no other better word for that.
But anyway, it deals with ambiguities or disagreements in the model terms.
And an example I came up here with, which I thought was kind of interesting,
was like you can imagine in a database, a customer table, right?
And maybe the customer table gets filled in every time someone registers for the website.
But strictly speaking, a customer is someone who buys something from you.
And so we may be using that table for, you know, login information as well as customers. And so
later down the road, when an accounting person says like, Hey, give me every customer who's
been to the site in the last six months, you might give them a much bigger report than they
were expecting because you included people
that didn't actually purchase anything
because they were in the customer table.
But to them, customer means something different.
Because you gave them a false cognate.
Yeah, that's right.
I false cognated them.
Still, that's one of my biggest things
with the domain-driven design thing
is just some of the definitions and the vocabulary you got to use.
Yeah.
Ridiculous.
So now we're on to the actual strategy part.
So we've talked about how hard it is to kind of keep that integrity, but now we're actually going to give you a couple of tangible solutions that you can go and start running with today.
And the first, and a lot of these are going to be familiar.
We're kind of, we'll kind of skip around a little bit and keep things moving quickly, but the first is just
continuous integration. And that basically deals with code
reviews, merging changes infrequently, and running automated tests.
A lot of times that'll include deploys and whatnot. It's basically just
a common strategy for any sort of organization of any size, I'm sure.
It by now has some sort of continuous integration solution set up.
And the idea there is that you're going to catch problems and be able to fix
them quickly before they propagate out and become worse.
So I think probably most people are familiar with that.
If not,
you should Google continuous integration because it's really,
really kind of cool.
And that's your dev opsy type stuff.
Yep.
The idea there is you check in a change
and then there's someone out there watching for changes.
There's some sort of server out there
that's watching for changes
and will automatically bring those in.
We'll do a build, we'll run the test.
If it fails, it'll send an email, something like that.
So that's really useful, especially as team size grows yes especially and next strategy is a context map
and this one um i thought was really interesting interesting because it basically just involves
whiteboarding your organization right so there might be a big block called website and a big
block called schedule tasks and uh you know a big block called website and a big block called schedule tasks and a, you know, a big block called CLI or whatever.
And it can be even broken down more than that.
But basically the idea is just to,
to draw out your bounded context and draw some lines, map the terrain,
and kind of map the people in the organization around it as well like who owns what what areas uh and and
you want to do this based on how things are rather than how you want them to be because
you know you may never get to where you're going right realistically yeah the pie in the sky talks usually take up way more time and a lot of times
no traction is made on them yeah absolutely and one thing i thought this was funny it's like while
you're mapping if you find something uh that's broken or bad then just draw a dragon and move
on don't don't try to fix it here don't try to force the people into the boxes that they aren't
actually in.
It can be really tempting, especially if you've got a diagram that's almost symmetrical.
It almost makes a nice, clean Christmas
tree hierarchy. There's like that one
person. We've got to make
this look right.
A lot of times I think that'll happen if you've got
two or three people or two more
teams that kind of jointly
own something.
And you're not sure who to put whatever.
So there's like this weird temptation to be like, well, let's give it to this guy because they've only got three items and this other
person has four.
And so there's this weird kind of a,
like draw to mapping things in a way that looks nice on paper rather than how
things are.
And so it just can be misleading.
And then people,
when people see organizational maps like that and they see those kind of
incongruities that don't map up with reality,
they just dismiss the chart.
That's true.
That's,
that's very true.
Yeah.
And also by drawing things out,
um,
there's,
uh,
you also want to kind of give them good names and those names actually help
enforce those boundaries.
Cause you're,
um,
you're bolstering that ubiquitous language that you're building, right? So by having these kind of teams or driven areas now, you're kind of building a community around
it, a very small community. So the next strategy is shared kernel and um this one's probably something that every
programmer has done at one point it's basically if you've ever taken a library out and made like
a core or maybe you can call it you know library or something that has um logic that's called by
more than one place so if you say got a command line interface and a set of web services then you might have both of those being separate projects but you'll have a shared
library in common that does all the kind of decision making whatever like your logins your
authentication your authorization that kind of stuff yep all that sort of stuff and then things
that are specific to the command line ideally will be in the command line project and things that are
specific to the web service ideally are going to be in that web service project uh doesn't always
happen that cleanly but and you'll know next time you start to run the command line interface so you
get a call from the customer saying that uh it's you know um failing because uh http context is
null or something hey wait i've got a question. And this is backing up probably a few things,
a few items past. So you mentioned that you should have organizational teams, like even
coding teams that surround bounded contexts, right? Because then people are fully aware of
things in those bounded contexts. And that I get it. I,
I,
I get the reason for it,
but what do you say to the effect that when you do that,
you have teams working in silos.
So there could be something that every team uses that or does,
they could all be done better if there was a unified way of doing it right or or even
at that point teams sort of get tunnel vision because they're locked into thinking about
particular ways of doing something right what is the solution to something like that because if
again i get the whole point of putting people in bounded domain areas, because
now you have super knowledge throughout that entire domain, right? And people know how to use
it. But now these people have very limited sight into the entire application as a whole and what
it means to the business. And on top of that, you could be reinventing the wheel, you know,
10 different ways, right? So, because that was one of the other things that you could be reinventing the wheel you know 10 different ways right so because that was
one of the other things that you said earlier is let's not recreate it let's let's maintain the
integrity but it sounds like the integrity is for the domain not necessarily your entire application
as a whole yeah absolutely i imagine with bigger organizations this is even crazier but um i think
the answer here that the book wants to give is um
project management and just kind of dev management maybe some architecture mixed in there um people
that are um knowledgeable enough about the big picture to say hey that sounds like something
team b was working on last week why don't you go check check with them they don't necessarily have
to have um like a iron fist about you know um deciding that things should be uh
shared or whatever but it might just be just a little tickle in their brain that says hey go talk
to you know go talk to suzy i think she did something last week and then hopefully those
people to get together and we can kind of cross those organizational boundaries and you know
maybe get a new bounding context out of it right maybe make a new shared library or something
but i definitely think that's one downside
to having the silos like it
and they don't really address it very well.
Cool.
It's unfortunate.
And then basically,
they tell you to make sure to consult the other teams
when you've got a shared kernel,
which is kind of tough.
Sort of common sense, right?
Yeah.
But one thing i did think was
interesting there is like this is an argument against a certain organizational pattern that's
really common we have like the c-sharp developers and the javascript developers and the database
developers and there'll be three separate teams but um what you're doing there is you're owning
that technology stack not necessarily the the domain So this is kind of an argument for organizing things by a
feature or by, you know, bounded context. Yeah, I've never, I've really never been a fan of the
split up by ability or skill set. Because I feel like that's so close minded. I mean, I get it like
some back in the day, or a lot of organizations still do it right like there's database people that that give you a proc and your hands off to everything right you just take what
you get and i feel like yeah i get the separations there but the problem is is now you can't come up
with more creative or better ways to handle things in some cases right and and and you lose focus of
the business at that point. And really
you're saying, no, you're just going to write the code that translates this or whatever. And
I don't know, one of the things that's always been a problem for me, and especially now that
I'm a manager is, is not prescribing how things should be done. Right. I mean, part of being a
programmer is being creative. Part of it
is it's an art, right? Like, yeah, I've said this, I don't know how many times if I give this,
if I take a task and you take a task and outlaw takes a task, we're going to do it three different
ways. There's no question. They're probably not even going to look halfway the same, right? Even
given the same expected outputs or requirements, it's all going to be different.
And I think you need that leeway.
And I think that's when you start separating teams at those various different layers that
you lose something, right?
You lose that integrated piece of a team that, I don't know.
I mean, you gain some skills, but you lose overall business view.
So anyways.
Yeah, absolutely.
And you'll see it all the time when I'm like a say database developer someone will deliver a proc that um
you know matches up with their expectation expectations of the uh the requirements but
when it gets you know run in the context of the website does something that totally doesn't do
what anyone expected um and uh you remind me of a saying i like a lot which uh in programming there
are no correct solutions.
But in this case, at least there definitely would be two wrong ones.
So the next one is a different kind of strategy for organization, which they call the customer supplier teams.
And they talk about an economy here where teams can sometimes be organized, actually,
kind of like we talked about with by technology, where you've got one team that's considered
downstream, and one team that's upstream. And so maybe the the Java people are writing web
services, and then there's a team of JavaScript developers that are consuming those services and
doing stuff with them. In that case, the Java team is downstream, right?
And the changes they make need to be reflected and used by the people upstream.
And they say in the book, like, you know what, those, we don't like those terms.
We want the downstream people to treat those upstreamers as customers.
So we're going to change the terminology
here and we're going to call this customers and suppliers. So the customers, they're, you know,
ultimately kind of more important, right? And they need to have their needs met or else the whole
thing is dysfunctional. So what needs to happen there is these teams need to, you know, communicate
somehow, maybe through a mediator, maybe, you know, meetings, but whatever, doesn't matter.
But the idea is just to make sure that they're on the same page and that the customers are
driving the requirements and they're not getting a bunch of stuff delivered that makes no sense to
them. And it actually, they go out of their way
to emphasize that we should really call them that
instead of upstream and downstream.
This kind of emphasizes
the
more
important relationship there, I guess.
And it also helps
with problems with the
teams moving at different speeds. You can imagine
places where the JavaScript people
are mocking out services,
and then when the services finally get delivered,
they don't meet that expectation or vice versa.
The Java people are pumping out these services
and the UI can't make sense of them.
They're not organized in such a way
that makes sense for the final product.
And of course, you're going to want to write tests at those
boundaries. And another strategy, I like this one, they call it the conformance, the conformist
strategy. It's basically if you can't beat them, well, what can you do? You can give up, right?
Let's say if you're a customer supplier, hair and supplier is not meeting your needs and you just do on your own,
you mock the data, you find some other way around.
It's not going to be pretty.
You could also take responsibility for the translation,
which is not too different from abandon.
I guess the band is more of like a third party solution where you could just
totally ditch it and just do something else entirely.
But second is more about just owning more of that process.
Maybe you start writing some of the services. And the third one is just give up and adopt their
model. And this is something that's probably more apt in like a third party situation. Like say
you're working with PayPal and they've got some kind of interesting differences between them and
like traditional credit card checkout.
So you may adapt your entire checkout process so that it accommodates them. And maybe credit cards become more of an attack on to the PayPal methodology, even though PayPal may be a smaller percentage of the pie.
And that's pretty gross.
We're going to talk about this here
in a little bit, but that's a big
reason, the driving
reason behind the
anti-corruption layers is it prevents that
sort of leaking and that sort of poisoning.
They do kind of
let you know that
sometimes you just got to
take a little poison.
Hey, listeners, do you hate spending time checking logs,
you know, running ad hoc queries,
maybe searching your emails for clues on production support issues?
It's especially bad when the customer tells you about the problem.
If that's the case, then you should take a look at airbrake.io.
It's a service for alerting and monitoring so you
can proactively address issues and spend less time playing catch-up. It's especially important
with customers. Now, airbrake supports.NET and all major programming languages and platforms,
and you can see them all on their GitHub page. There's also a free trial, which, thanks to your
feedback, no longer requires a credit card number. So you can check
it out risk-free at http://getairbrake.com/.cb. Again, 30-day trial, no credit card, getairbrake.com/.cb.
All right, so the next strategy we want to talk about is the anti-corruption layer.
We want to spend a little extra time on this one because it sounds cool.
Wait a second, wait a second. Is it anti or is it
anti?
I think this is important.
I don't know that we can get much out of this without
settling on the correct way of saying this.
Now, which one did I say?
You don't remember?
No. What do you think you said?
Anti. You did.
Alright, then that's the correct pronunciation.
All right, we'll go with anti.
Well, I don't know now.
I'm just not going to say it that often anymore.
This layer that we're talking about now?
Yeah, there we go.
So, the idea with anti anti-corruption layer
is to provide a little bit of buffer um because even greenfield systems like brand new systems
that you're uh creating from scratch almost always have to be integrated with legacy systems like
there's not too many systems that aren't connected to anything anymore. And so dealing with these two different conceptual models with the thing that you're writing, the things that you're interopting with can get really nasty.
And a lot of times those other external models can have kind of an unfair influence on your model and they can actually overwhelm the intent.
And next thing you know, you're programming around them rather than your own business needs and so the goal is to create a
layer that lets you push these things to the boundaries and we've kind of used this phrase
for a lot of different things especially when talking about like solid or just different coding
principles you know we don't want to let those third parties even if they're first parties, invade and influence our decisions
without those being conscious decisions, right?
We don't want this leaking.
We don't want it poisoning.
We don't want it influencing.
It's okay if we decide to do this stuff, but we just want to be really careful about it.
Well, this is where some of the stuff that he talked about was kind of
interesting to me because he was talking about the fact that you might even be aware of this
external system that you're integrating with. And so you make assumptions, right? The data looks the
same as what's in your system. And so you think that you could just map it over and that assumption
can really screw you up, right? Like you could have all kinds of corrupt data in your system at that point.
The other thing that he said was,
that does it, but, oh, doggone it, what did I say?
Yeah, that's exactly what it was.
That assuming just because you see it and it looks the same, making one little assumption can really mess you up.
So that's why this actually matters here is having that layer, even if it looks like it's all the same.
Yeah, I've seen a funny example where there was a system that would keep track of inventory changes.
And it would send a message kind of out on a queue that would say that the inventory changed. And it started out by having the entire inventory count.
So you would say, you know, like widgets 99.
And over time, at some point, that changed to reflect the change in items.
So a 99 would mean there were 99 new items added to inventory.
And a negative one would mean um you
know one item has been removed from inventory but there were still some systems that were kind of
expecting to be the total inventory and so they were just going crazy and uh having the numbers
updated all the time to really no low numbers uh and so it caused all sorts of problems and
uh ended up needing a lot of fixing unfortunately but. But the field names didn't change, right?
And they were ambiguous enough so that it wasn't obvious.
And that's a perfect example.
It's a number.
The types matched.
The name of the column matched.
Everything matched except how it was being used.
Yep.
And that is the key.
And another example I kind of gave earlier is the paypal thing and even some
credit card processors um a lot of kind of um i don't want to say less mature but just like a lot
of simple implementations of credit cards will um kind of often charge in one step but as things get
more complicated sometimes you'll need to authorize and then as things ship in order to keep like the
liabilities straight for accounting you'll kind of um charge that card in pieces and so um paypal is even weirder sometimes because they've got some weird
rules around and there's a whole authorization step where you actually jump out to the website
and jump back and they've got some different rules and so if you're not careful um those rules can
end up leaking into and influencing your design and so you end up kind of hamfisting other things
that may even be more important
in order to kind of fit that model.
Next thing you know, you're trying to explain to accounting
why their liability numbers are off.
And yeah, obviously you're the one that's wrong, right?
Well, yeah.
I mean, even talking about some of the specifics there,
I remember that one of the things that was different
was the authorization, right?
In some cases on a credit card, that'll lock funds for a certain amount of time.
With PayPal, it might do it somewhat like that, but it's not exactly the same.
So again, those two domains operate a little bit differently of each other.
And so if you make that assumption that they're the same, which we might have at some point, that creates all kinds of problems that really are a pain to go back and turn around.
Yeah. And what I think what I may have mistakenly done at the time was try to kind of
model the credit cards after the PayPal because PayPal was the same, but a little more complicated.
And so I ended up having these weird kind of do nothing methods in the credit card for
things like reauthorizing or whatever, or changing the amounts.
And it was just dirty.
And it meant that I was letting someone else drive the bus.
And, you know, so just it doesn't line up well with everything else we've been talking
about in domain driven design, which is letting the domain and letting your needs
drive the changes and drive the code and keeping everything in lockstep and you know what that
also goes back to a clean code episode where we were talking about integrating with third-party
libraries is if you create your you know what you need to happen, right? So you know your business need, create
interfaces that you adapt to those business needs. So you basically wrap those third parties and you
make those things operate the way that you need them to operate as opposed to like what you said,
you know, you took the more complicated one and said, well, they both have the same type
functionality. Let me try and cram the simpler one into the more complex one. And it didn't work. Right. And that's one of those
lessons learned after the fact, because it's like, wow, I had no idea. But that's where if you try
and if you code to your third parties and you take into consideration what your actual domain
needs are, then you can save yourself a lot of pain.
Yeah, that can be difficult though because if something really does have
like these different steps
and it needs different hooks in order to integrate,
then you can't just slap a simple interface on it, right?
And treat them the same.
So it's difficult,
but we're trying to minimize those sorts of things.
We want these pluggable pieces.
And we always make the argument,
especially about databases,
that you're not going to be switching
from SQL Server to MySQL in any sort of non-trivial app right it's
just not going to happen but we still want to kind of abstract things as if that were the case
because it protects us from other things and i've definitely seen applications that um are very
driven by sql and so um even i mean every decision along the way and it's probably because i wrote
them that way has been very much driven by that persistence layer.
And that's an example of something where there's an outside influence that's influencing my design.
And so now I'm thinking about the application, and I'm even making webpages or widgets
that are now influenced by my persistence layer, which is you know kind of wrong like it should be
influenced by my customer primarily the need right the need and i will say so that whole argument
about you're not going to change from sql server to oracle or to my sql or postgres or whatever
i used to be 150 behind that where i have differed now is i still agree with that i don't think you're
going to change the rdbms behind the scenes most of the time right like you're not going to jump
ship from microsoft to oracle what are you trading one big cost for another big cost that's not really
the thing what might happen though is you might need to introduce augmented other technologies, right?
So a search engine for speedier retrieval of things, a caching layer.
Because now, I mean, if you look at Stack Overflow's architectural blog,
great, filled with amazing amounts of information.
I've listened to the guy on another podcast, and he talks about, yeah, most of our interactions are reads. So we can cache most everything,
right? So when you start thinking about not, hey, I'm not going to move from this RDBMS to this
RDBMS, but you start thinking about, hey, what other things do I need to augment the stack?
So another thing, thinking about relational databases or even Mongo or DocumentDB, another
thing you might be thinking about is most people write directly to it, right?
Like every book you ever bought was, okay, you have this form and now you need to save
to the database.
It's going to tell you how to write your insert statement and all that, right?
The problem is now you've got a direct line to that.
What if you wanted to insert a queue so that you could start enforcing read or do once actions or retries or any like, that's where the abstractions become
important. And I hope everybody wraps their head around it. Yeah, the reality is you'll probably
never jump from from to a lateral technology probably doesn't matter that's not going to be
the case but the other of introducing other technologies to either increase performance or
to be able to view more analytics or to you know whatever that's where that's key that's where
things start really making sense yeah and um one example to think about is the database thing.
What if you decide you want to log all your calls, right?
You want to throw some aspects around there.
Now, if you have just been directly calling
every query, every spot, you have to
change almost every method in your
application, right? It's just not going to happen.
But if you had some nice, cleanly factored
services written around that, then suddenly that's
much more reasonable.
Yep.
And so the solution for dealing with these third parties just like we kind of talked about is creating an isolating
layer that handles translation in both ways and this can look like a service but it doesn't have
to be it could also be a library that you call a dll it could be an api that you create for somebody
else and the most common way of actually building these things is a combination of what they call it could be an API that you create for somebody else.
And the most common way of actually building these things is a combination of what they call facades, adapters, and translators.
And these roughly translate to the Gang of Four,
at least the facade and the adapter.
They have a little special definition of the adapter, which we'll get to.
And translator is kind of a specialized case that they define here.
And facade, I think we actually did an episode on facade on facade didn't we we did that and adapters i don't think we have translators
okay yeah i think they made up translator um so facade uh you should go check out that episode
but it's basically an alternative or simplified interface written strictly in accordance with
the other systems model so it just makes things a
little bit easier for you to use and ideally i thought this was really interesting ideally
they want it to belong in that other bounded context that's the thing that kind of bugged me
when i read this was like are you really going to have access to be adding code to their particular domain i
maybe you can add a service over on their side i think but that that one piece right there jumped
out at me yeah and so here's here's how i kind of reconcile that a little bit right imagine our
e-commerce you know we're amazon and we've got a front-end customer facing website and on that
website customers can log in, place orders,
right, put their credit card information in, whatever. Well, it's also maybe possible for
people to call into customer service and change their payment method, add items, change items,
maybe even place a whole order. You know, that's not outside the realm of normalcy, right? That
can be expected. So we don't want to duplicate that behavior.
And let's just say in this case, we want to go ahead and let that behavior live in the front end website.
But we want to have the admin kind of make some sort of web service call over there and say, hey, place an order.
Well, if you were trying to model that process like you're a customer, that is a pain in the butt, right?
You've got to log in as the person. So suddenly, you know, you're trying to like
look up the username and password
or like somehow kind of hack around that.
Then you're going to create a cart.
You're going to add those items to the cart.
Then you're going to like initiate checkout.
And I mean, it's just a pain in the butt, right?
To kind of like do all these steps.
And then if somebody adds a coupon step
or something in the front end website, now you're trying to kind of like model that behavior. And so ideally
what you want it is to have your website have a simplified facade for your admin to call that
says, you know what, why don't you just pass me a serialized order? That's got all the information
I need. I don't care how you put it together. Just give me everything I need to place an order and I'll just do it.
Right.
And ideally that code is going to live in the website,
which I thought was interesting because I think my first inclination is to
kind of do it in customer service,
like have it know those steps.
But really what you're doing is you're giving intimate knowledge of what's
essentially a third party at that part.
And so what they're saying is they prefer the facade live over there.
And that makes sense.
I mean, honestly, it makes sense from the that's where the domain knowledge,
that's where the bounded context exists,
so it's easy to leverage what's already there.
However, it does feel kind of weird for me to be customer service and say, Hey, I need you to
add me a customer service facade to your website, right? That's, I think it makes sense from an
ownership perspective because they can guarantee you, you know, certain SLAs, right? This is what this is supposed to do.
If you pass me this, then I can make sure that happens.
So I get it from the ownership.
But a lot of times when you're integrating with some third party or external system,
you don't necessarily have the ability to add to that system.
Yeah, absolutely.
And so, yeah, I think you're just straight up out of luck there.
But there's definitely some nice bits about having a facade over there.
Like one, it puts the ownership on them, and they're the ones that are more likely to know that something needs to be maintained or something relevant has changed.
But it also opens the door for other clients or other consumers to call, right?
So now if there is that command line interface, or maybe there's like a vendor portal where vendors can place orders on behalf of people or you know whatever can communicate to the website then now they can use
this simplified interface now so yeah there's lots of benefits to it just feels kind of weird right
and there's nothing to say also just to point out the recommendation is it lives over there but it
doesn't have to you could still write your own facade on your end and have to deal with all that hairiness like what you talked about right like how
do we fake the login how do we create the cart how do we do all this you can create it on your end
but now if that system changes the onus is on you to know about that and have to respond to it so
there's definitely some fragile situations that can come up from that.
Yep. What they're going to say is like, you know what, if it's looking like you're going to have to build a facade on your side, then why don't you consider writing an adapter instead? And
the adapter allows your client to use a different protocol than the implementer, which means that
you've got something that kind of matches your language and matches your expectations
and lets you perform
that action. So that would be the case, or that could be the case, but isn't necessarily the case
where you take that action, you go and log the customer in, you add the cart, you place the order,
you go, you know, add the address, select a billing method, whatever. That all can be adapted. And I
think the main difference here between the adapter and the facade that
they're getting at is that the facade is written in their language. It's a simplified stripped down.
It's for them. The adapter is written in your language. And an important distinction that I
think gives you get there is that you can have multiple adapters for a similar type thing. So
I can deal with, you know, I could say, you know, place order
and it may place that order on amazon.com, but Amazon's, you know, a big thing, right? They've
got, um, smile.amazon.com. They, you know, they, they've got a bunch of subsidiaries audible.com
and there's a lot of mixed matching going on. You know, you can order audible books now on
amazon.com. And so there's a lot of weird crossover there.
And by having adapters, now it's speaking in your language.
So I can say, place Amazon order or place Audible order or diapers.com order, whatever.
That wouldn't really work with facade because the facade is all about modeling to their expectations and simplifying their expectations.
I mean, talking about this, they, they did bring up the fact that the adapter in this particular case, isn't necessarily a, a code specific type thing. Like when we talked about the adapter
pattern previously, right? That's, that is you creating something to make your code work with
external code so it's it's a layer in between right right this wasn't necessarily it's the same
general thought in that you want your thing to be able to hook up to this external thing but it was
more about the communication between the two right yeah? Yeah, absolutely. Yeah. And I, yeah, I don't mean to mislead you there,
you know, to me, that was just kind of like an added little, like kind of cool thing about using
adapters. Um, but yeah, that's absolutely not the main focus. The main focus is that it's in
your language. And so that's the main point of this is that, um, you're adapting their processes
to meet your needs and not the other way around facade is that and it
could be communication based right like so um it might be talking over edi and so that adapter is
going to be able to know how to go get that data from that external system and bring it into yours
or it could be going over http or it could be over some sort of binary protocol right like
i think that's that's one of the key things
to take away from this
is that's supposed to be the communication translation
between the two.
Yeah, absolutely.
And it's also in charge of,
well, you just said it,
but if you are doing connections
to a database on the same server
or you're calling out to a system processor,
you're writing to a file or reading from a file, whatever.
All those things are examples of adapting.
So you're taking your message and you're adapting it to their needs.
Yep.
And the translator is the third pattern they kind of referenced.
And what they said there is the translator is actually kind of a little piece of the adapter. And the translator is specifically meant to translate concept to concept.
And so an example might be if you've got one system that passes you JSON and it's got a state ID and you need state code.
Or they've got an F name field and you've got a first name field.
And so it's literally just about transferring that data.
And so it's a little piece of the adapter and the adapter deals with other
stuff like,
you know,
the HTTP context or,
you know,
or,
um,
transport,
um,
EDI,
whatever,
but the translator is literally just data to data.
Yeah.
The,
the translator is kind of dirty right because if you're getting
you you'd have to potentially have a translator for every single type of adapter that you're using
or even even different types of objects coming from the same adapters right if some stuff's
coming across in xml other stuff's coming across in json other stuff's coming across binary right
this translator is responsible for taking data out of those which aren't necessarily objects stuff's coming across in JSON, other stuff's coming across binary, right? This translator
is responsible for taking data out of those, which aren't necessarily objects, right? Like
XML is not an object. It's a hierarchy of tags. You've got to take the data out of that and
marshal it into your domain model. And then when your domain model saves or does something and
maybe it needs to communicate that back out, right?
Like your whole point of the order system earlier with customer service, right?
Customer service all of a sudden needs to place an order for a customer.
It's going to compile all that stuff and send it out through this adapter
to the facade, hopefully, right?
And then at that point, that thing's going to create an order.
And that probably needs to return something back across the wire.
Who knows how it's coming over?
Is it just plain text?
Is it XML?
Is it JSON?
Whatever.
It comes back across, probably from the facade, through the adapter, into your translator.
And now that translator needs to turn that thing back into, say, hey a response this is the new customer order right so it's a it's a fairly
complex you know chain of events that have to happen there yep absolutely and uh that's it for
the three patterns um but uh they did give us a couple rules for consideration for anti-corruption layers.
And we'll just kind of get through those real quick.
They can be bi-directional, so we kind of talked about that.
You can call out.
You may also offer some services that allow other bounded contexts to call into you.
You can include the facade for their system if you need to. Preferably, you wouldn't, but you can include, uh, the facade for their system. If, you know, if you need to, uh, preferably you wouldn't, but you can, you can also have your own facades. Um, one thing they, they present, which is true. And I think a lot of people may not, uh, or sometimes you may be so anchored in our code and their code that we may not think about it, but sometimes you can refactor the other system to make your life easier it may not necessarily be you doing it you know you may cut them a couple tickets or um you know and maybe you
maybe you go out to github and make some tweaks to whatever to enable um what you want to do
but it's you know it's an option and something to kind of keep in mind and try not to be so
anchored and you're you know not invented here um you can consider modifying your model to fit better with theirs.
That's part of that leakage. That's kind of what the anti-corruption layer is designed
specifically to prevent, but sometimes it makes life a little bit easier. And so
you just got to go with it and be careful to only add functionality if it's specific
to the relationship of those two systems. And what that means is, in this specifically in this anti corruption layer, we only want to add things
that are specific to both of those. So like history, like a transaction log or something
or logging here, or, you know, we don't want to have any business logic here, we don't want to
making decisions that stuff needs to be living in one of those two systems proper and not in
this translation layer specifically in those bounded contexts and those aggregate routes
you know if we're talking about domain driven design yep yeah and it doesn't really make sense
to have a rule that's only in this weird weirdo layer between two worlds right because yeah i mean why
it just doesn't make sense it should just be mapping data across yep pretty much and there
was one other thing i did want to point out that he brought up at the very end of this whole thing
that i thought was key there's always a cost to integration always right and creating this
anti-corruption layer can be time consuming
and expensive and so you should make these considerations before you jump in and say yes
we need this because anytime you do that like that's another layer you have to maintain and we
we alluded to it a minute ago with if something changes on one end your system has to be updated
to be aware of that and And those aren't necessarily going
to always be talking to each other, right? Like it's not like the customer service department's
going to say, Hey, we made a change to this. And all of a sudden the website's going to be aware
of it, right? If these two things are working in a vacuum, but yet there's something that is
tying them together, that's a potential risky situation right there. So is it's interesting it's funny he also you read the
whole thing about the great wall of china right yeah he he had a pretty decent analogy i thought
that you know the great wall of china was built to sort of keep chaos down keep commerce going in the chinese empire and it actually bankrupted the the chinese empire at one
point at least one of the one of the time frames that was yeah yeah dynasties that was going on at
the time and it's expensive to maintain when you're building something that big right like
and all you're trying to do is create this barrier. And that's what these anti-corruption layers are. They're these, these barriers, these layers to, to keep these things
working together. They're expensive, man. Like, and depending on how complex it is, it can be just
crazy. So take caution, right? Like, don't just go building this because you think, Hey, I heard
about this anti-corruption layer thing. This is what we need to do.
These things have a trade-off.
There's a cost.
There's a time resource thing.
And there's always the opportunity cost, right?
Like if you're spending time working on this,
what features can't you add or that kind of thing?
So there's all kinds of things to take into consideration. You can always get the other guy to pay for the wall.
Hashtag political.
Oh, man. A couple couple other strategies we've got here
um this is one of my favorites too kind of like the conformance style they call it separate ways
uh which is basically give up um sometimes it doesn't make sense to uh to try and and take
care of uh everything you don't need to boil the ocean and one kind of example i thought over here
is like um mint.com pulls some data from I don't even know how many financial institutions, right?
So you can go and you can give them your bank info, your 401k info, everything else, right?
And they'll come out, they'll go out and grab all the info and bring it back in, show you some nice
graphs. But there's no way to do 100% of all financial institutions. It's just impossible. And I think that the only strategy they really have is to just do all that they can feasibly.
And if somebody, you know, can't see their, you know, bank account at some, you know,
podunk, whatever, you know, they can't count the number of pennies in your penny jar.
They don't need to send out a team of people and deal with that. They just say, you know what?
You can't see your pennies on our website.
We're sorry.
Like cities will have buses, right?
And buses go around, pick up people.
They have routes.
They have times.
They get a flat tire.
The bus is late.
You know, they're not sending a plane to come pick you up.
So then that's just, you know, a fact of life.
And so I think that it's okay to not handle 100 of issues but you do need to kind of think
about it and you know just make a constant decision as to what happens when things break
or if something is just not worth implementing because you know it's just not worth it right
i see a lot of times too like um a lot of e-commerce sites when they first start out
like they'll get a real simple solution whenever they they get an order, they'll get an email that says, hey, this person bought this thing.
You better go ship it.
And as that business grows, they're probably going to want to get out of that.
But that is a good, nice stepping stone.
But sometimes orders get lost or emails get in the junk folder or whatever.
So it is what it is, but sometimes it's worth it.
Another strategy,
open host service. And that's basically where you consider publishing an API or maybe like an SDK or something to make it easier for people to integrate with you. And it kind of saves you
some work because you're not trying to deal with all the customer support issues that arise from
them trying to do all sorts of wacky stuff with your uh with your data and the final strategy here that they provide
is a published language and uh this is this is really funny they actually um mentioned a hot
new language called xml being a common uh way of inter interrupting between systems so it gives you
a little perspective on when the book was written uh now i don't know anyone who
still likes working with xml except for maybe me xml is painful you don't like it don't lie
but the other other languages like midi is another good example where it's kind of again
uh a language that's a lot of devices know how to speak and so it made sense to uh kind of try
to normalize the data inputs and outputs for all these different devices
into something that's common.
So if you're in this, you know,
one in a million kind of scenario,
you may want to consider developing
your own protocol or language.
Have fun with that.
All right.
And with that, it's now time for us to beg.
So I got to say, we get reviews and we honestly read them.
I read every one of them.
I think I go to the site, all the sites every day, and I'm like, refresh, refresh, refresh,
right?
I want to read these.
I love them.
We got some this last time that were like, hey, man, I'm learning while I'm driving around.
This is keeping my brain engaged.
It's funny. It's all the things that we hope to do, right?
We hope to entertain, we hope to educate it and we hope to ignite that passion. So thank you to all who take the time to go up there and leave us a review. It seriously does make our day and it
really drives us to want to do more of these, right? Like here we are
recording at midnight on a Wednesday and you know, after a full day of work. So thank you guys. We,
we appreciate it. And please, if you haven't already do go leave us a review. It's, it's
your way of giving back to us. And also if you want some cool free stuff, you know, go up to
our website, www.codyblocks.net,
and the little newsletter section over there on the right.
All we want is your name and your email, and we'll basically just give away stuff.
That's been our status quo.
It's not every single email we send out, but it's probably 90% to 95% of them.
So go do that.
And again, thank you all for you know supporting us leaving us reviews
and listening yeah we got three jet brain subscriptions to give away right now i actually
need to get on that email i'll say that for tomorrow that's getting a little late excellent
but first it's time for it it's www.cuttingblocks.net slash review that that was a complete
fail on my part all right all good uh now it's time
for outlaws favorite part of the show survey says nice yep thank you uh do you know what invariant
means so this is something we talked about a lot last episode and uh well like i don't even know
if i would have said yes or no after, but maybe after.
But what do you think the audience said?
Man, I'm hoping they were all siding with us and they were like, nope.
So I'm going to go with, unless everybody's trying to be a smarty and a know-it-all,
I'm going to say nope, 40%.
No, there's only two answers.
Nope, 60%.
All right. So actually. Nope, 60%. All right.
So, actually.
Man, come on.
Yeah.
So, sorry.
The answer was yep.
Yeah, people did know what invariant meant.
And you want to take another guess on that percent?
Now that I told you that way off.
65.
65.
Oh,
Oh,
come on.
75.
This is bull crap.
85.
You lie.
Just tell me this is making me sick.
It's almost 90%. I don't believe this.
Is this a bunch of college kids that answered this?
Like everybody just got this in class or something?
Yeah.
Feel free to leave us a comment and let us know why the heck you know what invariant means.
Right.
I mean, it's one of those things.
You remember when we had the episode of boxing and unboxing and.net and what that actually meant?
I'd never heard anybody use those terms ever.
Yep.
Until Vlad.
Yeah, until Vlad.
Vlad, thank you for being the only person who has ever said that in a conversation ever
on the planet.
But at the time, I would have been like, what's that?
Same thing with invariant.
Who says we need to make sure the invariants match up yeah right no anyways that's a shame um and so apparently
we need to learn some more yep yeah or you guys need to get out more you know one of the others
i don't know yeah yeah i'm gonna go with that that makes me feel better. Oh, boy.
Actually,
now it's time for the next survey.
This one, actually, we got from Joe Recursing Joe.
Joe Ridley.
Thank you very much for sending that in.
I don't know
what you've done without you,
so we need it tonight.
Apparently, we lost our outlaw.
The survey for this week is at what speed do you
listen to your podcasts and i should have come up with something more clever outlaw always does but
all i've got are times here so we're looking at like 0.5 on 1.5 uh and two and if you're
somewhere in between just kind of pick the one that's closest um round up yeah
and then this is probably gonna make me feel dumb too when everyone's gonna be like
five but there's no way what do you do on i'm 1.5 almost everything i do 1.5 on podcasts but
books sometimes i will bump it down to one. I don't know why.
Really?
No, books I speed up because those readers, they exaggerate things a lot,
and so they slow down. Like Scott Brick is one of my favorite orators, I guess is what they're called.
But, man, that guy, just amazing reading ability.
But he definitely takes dramatic pauses a lot.
And so 1.5 is almost like it's listening to him at natural speed.
Yeah.
I don't think I've listened to anything for him.
Oh, dude.
He's good.
Have you ever listened to Orson Scott Card?
Why can I not think?
Ender's Game?
Ender's Game.
Have you heard that one?
I don't know.
He reads the entire series.
Oh, really?
I definitely didn't read the whole series.
He's good, man.
He's really good.
All right.
Speaking of game shows,
I also tried to think of those Googles.
I forget what I was calling them.
I looked up programming is for.
What do you think?
Number one responses.
Programming is for nerds.
So that's what I was expecting.
Losers is number two, actually.
But the number one answer for me at least is programming is forgetting
not for space skating but forgetting one word oh wow that actually does for me too if you don't
put a space yep and uh i googled that phrase and i found a lot of people um writing it and
it's actually funny because it's uh it's for a lot of different reasons there are some articles
like about programming is forgetting which are basically based around abstracting.
So you kind of build up these abstraction layers
so that you can think at higher and higher levels.
And so it's all about kind of pushing that other stuff
and those details out of your head.
But there's also a lot of people talking about
things that they have forgotten or they've relearned
or even looking at their code and forgetting what the heck it does does so it's just funny to see that there's someone so many people
about programming and forgetting together that's interesting and losers wow that's that's harsh
yeah the nerds nerds would have sort of been the last place when they're what number six
it says programming is for geeks man google the google sphere is harsh i think this is google feud right
yeah there we go i like it this episode is sponsored by linode linode has 10 data centers
around the world with plans starting at five dollars a month for one gig of ram and 20 gigs
of ssd storage and can go all the way up to 200GB of RAM with 16 CPU cores
for all your heavy computing needs. And all this can be done in under a minute. Linode uses hourly
billing with a monthly cap on plans and add-on services, which ensures you'll never get in over
your head. You have full control of your VM, so go ahead and create Docker, encrypted disks, VPNs, and more.
To get a promotional credit of $20 towards your Linode hosting, which is up to four months free,
go to www.codingblocks.net slash Linode, that's L-I-N-O-D-E, and enter CodingBlock17 to get started today.
All right, so I think, is this the last section that we have? This is.
All right. So this wasn't necessarily in Eric Evans book, domain driven design. This was
something that is augmented. And honestly, I got it from the poolloSight course that Julie Lehrman and Steve Smith did together.
And I went out and also looked up a little bit more information on it as well. So what we're
talking about now is domain events. And really the concept is pretty simple. We'll get into some of
it here, but this is a nice way to augment your domain driven design patterns to where you can further yet again
abstract and decouple certain layers from each other and and we'll talk about some specific
cases where that that makes sense so first let's talk about what they are they are used to capture
something that happened that happened past tense in the domain it's go ahead i was just trying to think what happened
being okay so uh you know uh processed order processed payment not it happened not right
not processing payment or something it it happened we We just did it. So that's when you start thinking about a
domain event. A good practice is to include a date time to indicate when the event occurred,
because you'll probably need that when you go to do whatever needs to happen on it.
It's a good idea to also in the payload that goes with this domain event is to include the aggregate, the aggregates
entity IDs as well, because maybe that stuff needs to go along for the ride. So maybe your order ID,
if, if you're doing some sort of like I process this order, pass along the order ID
and each domain event is its own class. And the way that I related this in my mind is, and I've never seen too many people do this,
but if you create special exceptions for your own classes,
you typically create an exception per class that you're doing, right?
So if you have an order placed exception or order allocation exception, whatever,
you're going to create specific
ones for each one. And so this is the same type concept. And this one is key. Raising the event
should have no side effects or behaviors. And that seems kind of odd because you're going to say
order processed, right? You raise that event, then something's going to happen,
but it shouldn't happen in the object that's raising that event is I guess
what I'm getting down to right in the scope of where that's being raised.
You've already done everything that you expect to happen on that entity or
that aggregate route or whatever,
that thing should be raised so that other things
can operate on it typically external services okay i'm kind of thinking like a pub sub type
model like um i might attach some sort of listener and says hey when an order is placed uh placed
like blink a light like steve from um grc what's the name uh security now whenever he sells a
copy of spin right he's got a little flag or a light that goes off.
Yeah, so I've actually got to know a little bit further down.
This is totally PubSub.
And it's kind of a lightweight of doing it because there's also, I think, CQRS.
There's domain events with event sourcing.
And that's way more complex.
This is literally just a simple PubSub type thing.
So in doing the research for this, one of the articles I came along on that I really
liked, I liked his approach, was Lostechies.com.
Jimmy Bogard wrote an article back in 2014, and he called it the Better Domain Events
Pattern.
And so one of the things that he talks about here
is one of the final patterns needed
to create a fully encapsulated domain model,
one that fully enforces consistency,
boundary and invariance.
So what he's saying is,
if you really want to complete your domain driven design,
you really need to integrate this stuff.
And by the way, I didn't see it on their site. And I think Julie Lehrman and Steve mentioned it in their course on Pluralsight.
I think there's a NuGet package, or at least there's an open source library out there for
domain events that you can just get. And so it's easy to hook it up and set up your event handlers
and add in your domain events. So there are a good place to start so you don't have to
try and reinvent the wheel and recreate all that stuff. But what he goes into in this article that
I thought was really important is in your typical way of doing it, let's say that you take, I even
wrote down something so that it would make a little bit easier.
Instead of firing off the domain events directly in your method,
because the problem with that is if you think about like a static method,
like process order or something like that,
you do all your stuff in there that needs to happen.
And then you raise this event directly in that method. Whatever's responding to that event. Now you potentially can get side effects because it's going to happen inside the scope of that method that was called process order, right?
So process order, you might say, go allocate, go do whatever, right? Charge payments, blah, blah,
blah. But then you're going to call this raise event order processed. Whatever's listening at that point in time is going to operate on that
thing, right? And so before you even returned out of that method, something else happened that could
mutate the state of that, or you could have some problems. And it's not testable either. If you
have a static method like that, that's firing off, you got no way of actually hooking into that with a unit test, right? Not, not without having all
kinds of crazy side effects. So the pattern that he said was, okay, instead of saying,
you know, this dot raise event or, or raise event add it to an events collection so within your method for process order instead
of saying you know raise domain event here and then creating the new one instead of that you
add it to an events collection and say hey you know events.add new order process type thing
now here's the cool part after After it gets out of there,
when you get, when you're done with this thing, right? Whatever the entire overall transaction is,
then you get into a state where it says, okay, now go run these events, right? Go raise all
these events in order that they came in. And then that way it's outside the scope of any of the methods. Now
you're probably down to the area where you're about to persist this data. And so at this point,
you need all the other things to happen. And so it happens outside of the scope of anything,
but it operates. Does any of that make sense? I hope I'm kind of like avoiding race conditions
where maybe I'm still kind of doing stuff. i raised the event and now somebody's trying to come in and poke
holes in my in my stuff right right and it's a way of ensuring that your entity doesn't get
modified at the wrong time right like and all these external because if we think about it right
so we've all seen systems i know you and have, we've seen systems to where order processed.
And then the very next line would be something like, and I think I even said it, the allocate
inventory, right?
And then the very next line inside there is ship line items, you know?
And so there's this very procedural way of, okay, now go do this.
Now go do this.
And it's all inside that process order method, right? Instead of doing that now,
when you turn this thing into a domain event, you don't have to be aware of all these external
things that have to happen. All you have to do is make sure that you send up the data via that
domain event class that you created and said, order processed. Now, if you have a service out there that allocates inventory,
it can be listening to that order processed event and it handles when it's done, right?
That thing raised, it goes allocates inventory. You have another service out there, ship line
items. That thing listens, it handles the event, that order processed thing, and it will ship the line items. And then if in the future,
some new thing comes along, right? Like maybe add to customer service rewards or customer rewards
points, right? All of a sudden you add a new service to that. You don't have to go touch this
code. All it's doing is raising that event. This new code can be sitting out there. It's brand new.
It's sitting on its own. It's in a service. It's decoupled. You just hook it in and say,
listen for this event. And when this happens, then go run this code. So it's a very clean way
of decoupling your domain from all the other services that might need to hook into things
that happen in that domain. Now, what about intra-domain events?
Does it make sense to maybe have something in my own domain
or my own bounded context that is watching for events?
I think it could all be handled the same.
I mean, if you were going to go that route,
I would think that maybe you could just use some sort of encapsulation
to make sure that it doesn't leak out.
I don't think there's anything that stops it from that.
I didn't see anything specifically that addressed it, but I mean, it's the same concept, right?
You're still going to have a PubSub, but it might be internal.
Yeah, I guess the idea is like, why wouldn't you just call a thing?
And I guess the only reason you would really need to do the PubSub there is if you need some sort of dynamic,
you know, whatever going on.
And yeah, I mean, that's kind of outside the idea of domain events.
So it's just kind of eventing in general, right?
Right, right.
Well, I got another one for you.
Okay.
What if I want to cheat and do like before events?
So I could say like before server shutdown.
And the server shutdown hasn't happened yet,
but the before the server shutdown has happened.
And the example I kind of think of there is like,
if you're playing like an online game,
you might get a message on your screen that says like,
server shutdown in 15 minutes, you know, save and sign off, whatever.
And so I thought it was kind of a funny little interpretation
of the event has passed because the event that has passed
is 15 minutes before something happens.
I don't know what to do about something like that.
I mean,
cause you're saying that it's happening out of order,
right?
No,
I'm just saying like I'm raising an event that's a,
that seemingly seems like it's hasn't happened yet,
but really I'm just,
I'm just muddying the waters for no reason.
I think you are,
but I'm curious though,
like how could we follow that through i mean the the whole idea of having like the before because what i'm thinking
about there is like let's say that you have order processed right as an event you could actually
have something using aspects or something that would automatically wrap those into a before and
after you know during or something like that.
But to your point about, you know, something that actually happened that it's lying to you about, I don't know what to do.
Well, it's not to say lying because the event would say before shutdown.
Like that would be the event name before server shutdown.
It wouldn't be, you know, telling you ahead of time.
It would literally be like a warning.
Like, hey, we've,
we've come to the point in time that I should be warning you about something
that is going to happen. And so that point in time has passed.
And that's the event that I'm notating. It's just a confusing,
but I think that's also where you put the date stamp on it and that helps,
right? Like you can, whatever service is listening
for that thing, if that is the case, then it can somewhat intelligently decide what to do at that
point, right? Like if all of a sudden it gets it and it's like, wait a second, that was 10 minutes
ago. You know, maybe I can't do anything right now, but, or I do, I have 10 minutes before it
happens. I can go ahead and save these things i don't know but i think i that
was one of the key things from the plural site video that i really liked was the fact that if you
if you time stamp that thing that could tremendously help you out right because that could
also take care of any race conditions or anything else that comes up right if you need to worry
about concurrency or anything like that so i was thinking too about that. Like, EXCGS, for example, does a lot of stuff
where it'll be like some sort of persistence store dot before load,
and that's where it'll kind of gather data that it needs to do its thing,
and it'll have an afterload method,
and it'll have these kind of different lifecycle events.
And I was just kind of thinking about what it means to say
that these domain events are always in the past.
And I'm like, well, the before loaded, I i mean the before time is definitely in the past now so i was just
trying to think if those were kind of oh so i see what you're saying now so that's interesting
because the extgs way that you're talking about which anybody who hasn't doesn't know what we're
talking about it's a javascript framework slash library slash api slash widget
creator that you can hurt yourself trying to program um i do love the events though but there
are no events i can think of that are like loading you know yeah it doesn't make sense to do that if
you wanted to have like some sort of like full screen mask that says loading or whatever you
would hook that up in a before load because it makes sense you say before i even try to run this go ahead and put the mask up and then after load let's take it down but both of
those events really have happened in the past at that point so by the time you're actually throwing
that screen up it's in the background going on and loading something else in a separate thread
so it's interesting because the pattern that they follow is like let's say render right because
render is one of the big ones that they have that really fires after it's rendered so if they were going to name it properly it'd be rendered
but what they do so to your point and this kind of goes back to the aspect thing what they do is
before it calls that main method it looks to see or it fires off an event and it through the
javascript way of doing things it
depends the word before before whatever that that event call was so before render will be run first
and if that thing returns false for any reason then it won't even run the render piece of code
if it returns true or doesn't return anything at all then it'll run the render so it'll fire the
before event then it'll fire the render event and then'll fire the before event, then it'll fire the render
event. And then after it's done with that, it'll go ahead and fire the after render event. So
to your point though, I think those are all still in the past because it's only firing those events
after they've completed that particular step. So, so before loaded step is complete right right so i think that's where
that's why they introduced that before render because and i mean unfortunately it's just a
naming thing that's sort of misleading and you could do the same thing here right you could
instead of naming it order processed you could name it order process or order process, right?
If you wanted or process order, something like that.
But that indicates that it's done.
If you wanted something to be able to do it before, then you could probably do something like an aspect and say, hey, before this thing runs, if there's a method called before, then fire that off or fire off this event or something.
I don't know.
There's progressive loading bars too
that you've probably seen in applications.
Like if it's a crap application or, you know,
if it's just not worth it,
it might just kind of spin forever.
But there are some applications that'd be like,
hey, it'll throw an event and say,
hey, 47% done now you should update the bar,
then 63% done.
But that should only happen
after that threshold has been exceeded
right yeah you don't
want it telling you that it's 70%
done when it's really only 65%
yeah Windows you listening
listening Bill Gates
I don't think Bill Gates cares anymore
I wonder what his last commit was
man
I don't know
so I think that kind of wraps it all up i guess the uh the
domain events that kind of all make sense then yeah cool i actually i keep wanting to do stuff
more with events like whenever i'm playing around with like or unity i keep wanting to have these
kind of generic um you know player jumped or player hidden under player and because i want to keep having these separate systems that like show text or update a health bar
or whatever i want to have those things all kind of separated and clean i haven't really found a
good way to do that in a static language like c sharp so maybe i'm just missing it but i don't
want to i feel silly trying to like reinvent an event bus in a video game um it makes me feel
like i'm doing something wrong.
I wonder if, just out of curiosity,
if something like Rabbit and Q would work in a situation like...
Because really all it is is a queue, right?
I mean, even the PubSub whole event model,
it's nothing more than a queue of things that were raised
and then you have handlers that are supposed to listen to them
yeah i don't think i want to set up a whole service inside the game but i think i could do
the same or a similar thing by having just a queue and kind of pop to the fop and uh stuff on and off
there's event handlers in c sharp so you should be able to do it right yeah but then you have to
manage the whole adding and life cycle and stuff so it's like okay here's a player let me go hook
up all my dozen of events that i care about so it's just a pain in the butt could you do that through um
dependency injection yeah and that's the route i started to go down a few times but and there's
two main into dependency injection frameworks that are common unity and both of them were like
okay first thing you do is re-architect your app so this takes care of all you know all creation of
objects like well that ship has sailed maybe next project and i just haven't looked at i forget the
names of now but yeah it wasn't happening uh that makes sense cool well the the resources we like
we'll have those in the show notes again the plural site course can't recommend it enough it was excellent uh modern software architecture domain model cqrs event sourcing by dino esposito
that was also a very good one domain driven design uh the book that we are currently going through
and in trying to share that information with you yeah man a special shout out to herbert uh
i'm sorry my name herbert herbert ogreca.com
this is uh has a really nice write-up on actually the chapter that's been a lot of time i'm looking
unfortunately i found it after i already topped a bunch of my notes or just copy paste and stole
it from you sorry herbert but it is really nicely done and i'm looking forward to reading more about
your blog and uh we'll have a link in the show notes there. Cool. We got dddcommunity.org domain language.com and the lost techies or
lost techies article that I mentioned just a second ago for the domain
events.
So now it's time for my favorite part of the show.
This is the tip of the week.
It's the tip of the week.
All right. So joe what you got
i closed the window uh so um know thy debugger so i found a really nice list of tips for um
the chrome dev tools and we had there's actually just been a recent update but um this particular
web page that we'll have in the show notes has got like i don't know 15 or so different tips
and it's actually got a little screenshot showing you how to do everything from like print pretty printing in Chrome dev
tools to how to easily, uh, edit HTML and some of the stuff I'm sure, you know, but to skip the line
number, there's definitely going to be a few things that, uh, you'll probably get some use
out of like multiple cursors. Um, so yeah, it's just a, it's a really cool, um-up of and demonstrations of how to use chrome debugger
which is something that a lot of people are spending a lot of time in but not maybe realizing
that uh they're these really cool advanced options very very nice all right so mine let me open mine
back up real quick oh no go ahead man i found my favorite um toggle element state you ever do one
of those things where like you're trying to hover over something and you're like also trying to see it
in the uh in the inspector yeah like oh damn it and you're like trying to like even maybe even
like look into both try and whatever there's actually a little style thing there's a little
um if you click the uh little pin like the push pin at the top it pops down a little window and you can just click hover or
active or focus or blur and i'll just put it in that state oh i didn't know that yeah visited
yeah i mean it's just amazing that's beautiful so many times i've like tried to hover and look at the
what did it do? That's beautiful.
I didn't know that.
I will be visiting all those tips.
So mine is C sharp bass this time, and it's the explicit keyword in C sharp.
You know what that does?
No.
All right.
Beautiful.
So this one's kind of cool.
If you're trying to cast one type to another type, you can use the explicit keyword. And when you do the cast, it will run a particular method that you have. So you create an
operator. So in this case, you could say public static explicit operator. And let's say that you
want to convert Celsius to Fahrenheit or from Fahrenheit to Celsius, then you basically just, you can create your inline method there.
And then the next time you do that cast, it will use that operator.
It'll automatically cast it for you.
Oh, very cool.
It's pretty sweet.
So I didn't know that existed.
I mean, I've written conversion things before in the past.
I didn't know that I could sort of like override a cast like that.
And it's beautiful.
Yeah, it's very nice.
It actually reminds me, I was playing Rocket League with a guy from the Netherlands,
whose name is actually Guy.
He was a Netherlands high guy.
He mentioned being miserably hot because it's 30 degrees over there.
And of course, me being in front, I'm like, come on.
And then I realized I'm an idiot and I'm uh fahrenheit centric so i did the calculation it is indeed hot what is 30 degrees
hot is that 90 something it's getting there let me see i don't know i i feel like you're still
gonna be like come on you live in florida man It's hot down there. Yeah, but I recognize that it really truly is hot.
Yeah, it's, I don't know.
It is 86 degrees.
Man, that is just barely warm.
I think I'm used to it, but I still think it's hot. It's ridiculous that anyone lives anywhere that isn't just 60 all the time.
Dude, did you see, this is totally off the rails.
Arizona was hitting 120. it was too hot for planes
to fly i know they shut down airplanes like hey man it's time to move yeah all right so i did have
an additional tip of the week sort of similar to yours actually i found this great article which
is where i saw the explicit thing that was uh developer.com slash net top 10 tips for C sharp programmers, I think is what it really was supposed to be.
And he did.
He had some great tips on there.
So that link will be in the show notes as well.
So you get some bonuses this time.
And I think that was pretty much it.
All right.
Yeah.
This episode, we talked about about strategic design and domain events.
Don't forget to check out the show notes for
links to things like the video review
of Lenovo
versus the
HP.
And
yeah.
You need to go watch it. It's only
12.30 our time. You're going to watch it now, right?
And that's like, 12.30 our time It's only 1230 our time. Yeah, you're going to watch it now, right? And that's like 1230.
Our time is like 430.
My time.
So subscribe to us on iTunes, Stitcher and more using your favorite podcast app.
Oh, be sure to give us reviews by visiting www.codingblocks.net slash review. While you're
up there, check out our show notes, examples, discussions, and more. And send your feedback,
questions, and rants to the Slack channel, codingblocks.slack.com. You can invite yourself
by going to codingblocks.net slash slack. And also be sure to follow us on Twitter at
codingblocks or head over to codingblocks.net and find all our social links at the top of the page.