Coding Blocks - Software Architecture – Strategic Design and Domain Events

Episode Date: June 26, 2017

We'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)
Starting point is 00:00:00 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.
Starting point is 00:00:32 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,
Starting point is 00:00:59 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
Starting point is 00:01:46 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,
Starting point is 00:02:10 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.
Starting point is 00:02:25 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
Starting point is 00:02:58 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
Starting point is 00:03:44 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
Starting point is 00:04:12 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
Starting point is 00:05:03 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.
Starting point is 00:05:42 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?
Starting point is 00:06:25 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?
Starting point is 00:07:08 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
Starting point is 00:07:51 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
Starting point is 00:08:34 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.
Starting point is 00:09:13 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.
Starting point is 00:10:02 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
Starting point is 00:10:41 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.
Starting point is 00:11:11 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
Starting point is 00:11:32 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.
Starting point is 00:11:52 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
Starting point is 00:12:31 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
Starting point is 00:13:09 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,
Starting point is 00:13:44 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.
Starting point is 00:14:32 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
Starting point is 00:15:11 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
Starting point is 00:16:02 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
Starting point is 00:16:49 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,
Starting point is 00:17:19 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
Starting point is 00:18:12 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?
Starting point is 00:18:39 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.
Starting point is 00:19:15 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
Starting point is 00:19:44 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
Starting point is 00:20:26 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
Starting point is 00:21:01 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,
Starting point is 00:21:38 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
Starting point is 00:22:18 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,
Starting point is 00:22:52 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.
Starting point is 00:23:16 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,
Starting point is 00:23:33 um, totally, totally metaphorical, uh, not metaphorical, anyway, hypothetical. Um,
Starting point is 00:23:39 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
Starting point is 00:24:03 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
Starting point is 00:24:45 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.
Starting point is 00:25:19 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
Starting point is 00:25:45 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.
Starting point is 00:26:24 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.
Starting point is 00:26:52 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
Starting point is 00:27:10 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
Starting point is 00:27:53 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
Starting point is 00:28:20 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
Starting point is 00:28:54 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.
Starting point is 00:29:18 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?
Starting point is 00:29:54 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.
Starting point is 00:30:30 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
Starting point is 00:31:01 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
Starting point is 00:31:46 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,
Starting point is 00:32:40 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
Starting point is 00:33:26 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.
Starting point is 00:34:21 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
Starting point is 00:35:02 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.
Starting point is 00:35:45 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
Starting point is 00:36:21 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
Starting point is 00:37:00 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
Starting point is 00:37:35 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,
Starting point is 00:38:05 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.
Starting point is 00:38:22 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
Starting point is 00:39:01 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.
Starting point is 00:39:32 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
Starting point is 00:40:05 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
Starting point is 00:40:23 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
Starting point is 00:40:51 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,
Starting point is 00:41:22 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
Starting point is 00:41:38 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.
Starting point is 00:42:10 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
Starting point is 00:43:04 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
Starting point is 00:43:21 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.
Starting point is 00:43:42 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.
Starting point is 00:43:56 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,
Starting point is 00:44:04 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
Starting point is 00:44:59 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,
Starting point is 00:45:45 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
Starting point is 00:46:21 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
Starting point is 00:47:03 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
Starting point is 00:47:39 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
Starting point is 00:47:58 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
Starting point is 00:48:19 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
Starting point is 00:49:11 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.
Starting point is 00:49:47 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
Starting point is 00:50:15 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
Starting point is 00:50:58 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
Starting point is 00:51:39 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
Starting point is 00:52:11 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,
Starting point is 00:52:26 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
Starting point is 00:52:53 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.
Starting point is 00:53:21 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
Starting point is 00:54:07 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
Starting point is 00:54:23 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
Starting point is 00:54:50 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?
Starting point is 00:55:30 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.
Starting point is 00:55:47 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
Starting point is 00:56:20 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.
Starting point is 00:57:12 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.
Starting point is 00:57:49 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.
Starting point is 00:58:33 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.
Starting point is 00:59:10 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
Starting point is 00:59:26 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
Starting point is 01:00:05 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?
Starting point is 01:00:25 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.
Starting point is 01:01:09 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
Starting point is 01:01:54 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
Starting point is 01:02:29 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,
Starting point is 01:02:42 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
Starting point is 01:03:19 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.
Starting point is 01:04:13 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
Starting point is 01:04:55 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
Starting point is 01:05:39 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
Starting point is 01:05:59 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.
Starting point is 01:06:32 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
Starting point is 01:07:06 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
Starting point is 01:07:51 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
Starting point is 01:08:28 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
Starting point is 01:08:49 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.
Starting point is 01:09:17 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
Starting point is 01:09:47 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.
Starting point is 01:10:22 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
Starting point is 01:11:14 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,
Starting point is 01:11:55 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
Starting point is 01:12:37 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
Starting point is 01:13:36 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
Starting point is 01:14:18 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,
Starting point is 01:14:35 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.
Starting point is 01:14:58 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,
Starting point is 01:15:35 you know, or, um, transport, um, EDI, whatever, but the translator is literally just data to data.
Starting point is 01:15:42 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
Starting point is 01:16:09 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.
Starting point is 01:16:49 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
Starting point is 01:17:11 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
Starting point is 01:18:14 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
Starting point is 01:19:04 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
Starting point is 01:19:46 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
Starting point is 01:20:28 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.
Starting point is 01:21:27 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.
Starting point is 01:21:44 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.
Starting point is 01:22:31 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.
Starting point is 01:22:52 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
Starting point is 01:23:17 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,
Starting point is 01:23:52 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
Starting point is 01:24:36 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.
Starting point is 01:24:59 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.
Starting point is 01:25:18 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
Starting point is 01:26:03 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
Starting point is 01:26:30 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.
Starting point is 01:27:14 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.
Starting point is 01:27:30 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,
Starting point is 01:27:46 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.
Starting point is 01:28:01 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.
Starting point is 01:28:27 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
Starting point is 01:28:54 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
Starting point is 01:29:16 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
Starting point is 01:29:50 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.
Starting point is 01:30:30 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.
Starting point is 01:30:45 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.
Starting point is 01:30:56 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.
Starting point is 01:31:18 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.
Starting point is 01:31:52 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
Starting point is 01:32:26 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.
Starting point is 01:33:22 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
Starting point is 01:34:18 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
Starting point is 01:35:17 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,
Starting point is 01:36:08 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
Starting point is 01:36:41 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
Starting point is 01:37:13 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.
Starting point is 01:37:37 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
Starting point is 01:38:12 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,
Starting point is 01:39:02 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
Starting point is 01:40:02 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
Starting point is 01:40:48 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.
Starting point is 01:41:21 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
Starting point is 01:42:14 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?
Starting point is 01:42:54 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?
Starting point is 01:43:16 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?
Starting point is 01:43:34 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
Starting point is 01:43:57 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,
Starting point is 01:44:13 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
Starting point is 01:44:41 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
Starting point is 01:45:09 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
Starting point is 01:45:45 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.
Starting point is 01:46:19 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
Starting point is 01:46:57 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
Starting point is 01:47:44 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
Starting point is 01:48:29 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
Starting point is 01:49:09 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.
Starting point is 01:49:21 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
Starting point is 01:49:37 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
Starting point is 01:50:12 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
Starting point is 01:50:43 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
Starting point is 01:51:19 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
Starting point is 01:52:11 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.
Starting point is 01:52:44 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
Starting point is 01:53:27 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
Starting point is 01:54:12 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.
Starting point is 01:54:37 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.
Starting point is 01:55:17 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.
Starting point is 01:55:34 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.
Starting point is 01:56:12 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.
Starting point is 01:56:53 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
Starting point is 01:57:08 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?
Starting point is 01:57:25 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
Starting point is 01:57:59 codingblocks or head over to codingblocks.net and find all our social links at the top of the page.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.