 Well hello and welcome to Dev Nation Live. I'm coming to you live today from Salt Lake City, Utah because like always I'm traveling to go out and do presentations. I'll specifically be giving a presentation tonight at the local Java user group and one thing's super cool about Utah you guys should all be aware of they actually have Hawaiian Sun Passion Orange which I grabbed three cans of last night because this is my favorite drink in the world. If you're not familiar with it you should give it a try, but you normally have to go to Hawaii to get it. But to kind of introduce things today we're going to talk about domain-driven design. As always with these Dev Nation Live sessions we love talking about hardcore tech topics, showing you reactive programming, microservices, Kubernetes, anything related to the Java ecosystem, and we will certainly cover other topics as we go. But domain-driven design continues to come up as one of the primary things people are interested in because they want to hear more about that bounded context. They know it's the magic elixir to solving our microservices problems and certainly Justin is going to give us a nice introduction to that today and walk us through it. Okay? All right. Let me mute that. So you have to be cautious of the live session coming on while you're in it. So I'll be hitting it out where you guys on chat. So please ask your questions via chat and ask them verbally to Justin, but just keep in mind Justin works for our Open Innovation Labs department. He specifically is one of our senior consultants that goes out and work with customers for Red Hat customers working their way through the movement from the old world, if you will, to the new world of agile and continuous and domain-driven design as a key aspect, the key topic of that. So Justin, please take it away. All right. Can you hear me okay? Yeah. All right. Hi, everyone. Justin Holmes coming to you here from Denver, Colorado. And I'm going to walk you through domain-driven design for mere mortals. So let me share my screen here. Let me put that and I will flip over and hopefully you guys see the presentation right now. Fantastic. Okay. So let's jump into it. Let's look at the agenda for today. So we're going to start off first talking about why domain-driven design is relevant in 2017 and Burr started to allude to that in the introduction here. What we're going to do then is we're going to look to strip away a lot of the jargon associated with this community and really focus in on the principles of domain-driven design. And once we've done that, we're going to look at the bounded context. So this key pattern that comes out of the domain-driven design community. And we're going to look at some very tangible, realistic examples that are going to help put this concept into practice so that you can really see it in action. And then what we're going to do at the end is we're going to look at how you can apply the principles that we talked about earlier without necessarily reading one of the textbooks associated with this community. And those texts are important, but the reality is not everyone's got the time or patience to work through that material. So we want to look at all those things today. So in short, Burr kind of hit the nail on the head here. Microservices is really why most people who haven't been part of this community for a long period of time are talking about domain-driven design in 2017. And this is a reductionist view. There's other reasons to care about domain-driven design. But in 2017, this is really the driver that's bringing new people to our community. And so it's important then to sort of talk about why microservices have this connection to domain-driven design. And it's really around the optimizations that microservices make in your architecture. Christian Posta, who's one of our colleagues here at Red Hat, has done a lot of work talking about how microservices, more than anything else, optimize for speed. And they do that in two interesting ways. The first thing that they do is they reduce the size. And they also increase the autonomy of two different things. The first thing is reducing size and increasing autonomy of software components. But they also do that for delivery teams. And that's really important to think about. The trouble is autonomy is really hard. It's really, really hard. We can certainly break things down into smaller units. Most people conceptually understand how to do that. But enabling software components to be autonomous, to operate independently of other components when they're very small, and to enable teams and the processes that govern those teams, to enable those smaller teams to be autonomous, that's also really hard. And so let's think a little bit about that sort of in the day-to-day work that you do now. There's chances are, if you work on a team, that there's coordination between your team and another team. That might be to change the scheme of a database. It might be to change the contract of a rest or a soap service. But there's coordination. And that coordination requires blocking between the processes that these two teams have. And that slows us down. You've also got issues with autonomy in your processes, the release process that most organizations have, or maybe provisioning a VM. There's a lot of bureaucracy there, and that reduces the autonomy of teams. And then just from a technical perspective, things like transactional boundaries, using single sources of truth for data or authoritative data sources, these are technical components that reduce the autonomy of our team and the applications we write. And like I said earlier, Christian's written a lot about it. And so throughout this talk, I'm going to link to all sorts of other sources that you can use. Here, there's two links here to blogs that Christian's been writing. So with this notion that small autonomous services are the focus of microservices, the DDD community has been focused in this area for a long time. The original text was released in 2003. And last 14 years, this community spent a lot of time talking about how to build small autonomous systems. There's just been talking about it from a different perspective, from the way that we model the businesses that we work in, not necessarily from a technical perspective. So things like circuit breakers or so forth and so on, really focused from a different perspective. But building small autonomous discrete components to build larger systems, that's been the primary focus of the DDD community. And this is really why the community is coming, sort of having a renaissance today in 2017 with microservices. All right. But the problem is that most people who haven't really been steeped in the community are afraid of sort of the academic nature that we sometimes portray. And Burr likes the joke that often DDD requires a PhD. And the real goal of this talk, if you take nothing else away, is that this is largely a false statement. It is true that there's complexity and sophistication here. And that's because the mainstream design as a community is focused on tackling the inherent complexity in software. And it's not looking to simplify it. It's not looking to hide it. It's not looking to push it away. It's looking to address it directly. And so inherently, there's complexity here. However, there's a lot of things that we focused on that aren't really critical to understanding the principles of the main driven design. And when we actually look at those principles, I think most people will look at that as actually something quite simple, something quite sensible. So with that, let's start looking at those principles. And to do that, what I'm going to do is paraphrase a keynote that Eric Evans, the author of the original domain driven design text, he did a keynote at this wonderful conference that just happened here in Denver, Colorado. It's the first North American domain driven design conference. I've linked here to the videos from that conference as well as the Twitter handle. Red Hat had the pleasure of sponsoring this. And it was this really awesome opportunity to have these types of discussions that we're having here today. So invite you to check out those videos and also maybe check out the conference next year. So to that end, let's get into the keynote and some of these key principles that Eric outlined. So this was the fourth principle that he got to. But I think he highlighted this and others in the community highlight this as well, that what sets the main driven design as a community apart from other communities is a focus on a shared language within a bounded context. And you'll often see shared language written as ubiquitous language, which in most scenarios means the same thing. I like to use the word shared language because it's not as complicated. More people know what it means. And it's not as off-putting. But this focus on language within a bounded context is really the key focus. And we're going to look at that by example in a second here. The second principle is focusing on the core complexity and opportunity of the domain. And this simply just means that we're really striving to find the piece of software that we're building that gives our business a competitive advantage. And often that competitive advantage isn't one related to a messaging system. It's not related to a new data grid. It's related to something new and compelling that we can help our businesses bring into the marketplace to gain competitive advantage. And DDD says, let's focus on that. Let's keep that front and center throughout the software design and delivery process. The third one is really interesting. And we're going to look at some practical examples of how you can do this today. And this is that when we focus on the complexity and opportunity of the domain, our goal isn't to replicate real life, realism, and getting things exactly as they are in the real world. That's not our goal. Our goal is a model. It's an approximation. And we want to explore these models in collaboration, not just between software developers, but experts within the domain. And so that might be a product owner. It might be a business analyst or a systems analyst. The point being is the software that we ultimately write, it needs to be a model that's a collaboration. And the last bit is that ultimately this is about writing software. And it's the fact that our software needs to express the models that we build explicitly. And we're going to look at how models here are built around this concept of shared language. So real quick, let's just highlight what a model is. So when we talk about it here, we have a common definition. And you'll see actually here in Eric's keynote, he does a really awesome job of describing models in terms of maps and how maps have evolved. And he talks about this Mercator's model, which is a great sort of the standard map that you're used to seeing in a classroom. I'm not going to go through that here. We don't have enough time. But I really encourage you to follow the link and take a look at Eric's talk there. But again, the goal of models is to be useful. And it's important to understand utility is tied to a very specific scenario. And so when we talk about usefulness, we're not talking about solving every problem that's out there. We're talking about a model that helps us solve one problem and helps us solve it really well. And this of course leads to this notion that there's no one true model of a domain. A domain can be broken into different parts. And we're going to see that in a moment here. And as we break it down into different parts, we'll find that different models are useful in different parts of that domain. And this essentially leads us to the concept of a bounded context. All right. And this here we've covered. So what I want to do is I want to look at bounded context by example, and that the best example that I've ever seen comes from Martin Kleppen. He worked at Twitter was part of the original guys developing Kafka and then worked at Confluent. I think he's now at Cambridge. And he did this wonderful example originally focused on something called event sourcing and command query responsibility segregation. We're not going to cover those things here. But he did write this wonderful blog that explains a domain that you're probably familiar with. And this is Facebook. And he talked about the concept of a like in Facebook. And he said, think for a minute about the software behind Facebook and the process of creating a new like. So writing to Facebook's database, clicking the like button versus the concept of a like when you look at your Facebook feed or you look at someone's post. In both cases, the domain uses the word like. But what like means is very different in these contexts. So when I'm liking someone's post, that means something quite different than when I'm viewing maybe my timeline and I see all of the likes from all of my friends and everyone in the community. The same concept applies to Twitter and in other internet sites that you've used before. So when I create a tweet, I'm still using the word tweet when I write a tweet as well as when I look at my Twitter feed. But what a tweet means is very different in the context of creating a new tweet versus viewing my timeline. And that's really important. And this is essentially the idea of a bounded context. It's essentially the idea that I've got one word or one concept. But when I use it in a different context, it actually means something different. Even though the word is the same, the concept is still the same. But it's semantically different and has different meaning and has different importance because it's in a new context. And those different contexts probably need different models. They probably need similar but different data. They probably need different technical performance characteristics. They might even need different kinds of engineers and different kinds of domain experts. And this is essentially the idea of a bounded context. So to give you another view of it, I'm linking here to an article that Alberto Brandolini wrote. This is a banking example, but it's the same idea. Here we've got a bank account. It exists in two different contexts, one in an expense tracking context and one in a banking context. We've got the same word. It probably shares some similar data components. But banking is a separate scenario than expense tracking. And therefore, it's the same concept. But in these different contexts, it means something different. And this is essentially the idea of bounded context. And it covers what in the domain driven design community is called strategic design. And it's really important because this context isn't just a software boundary. So as we start to look at how this actually gets implemented, we can look at each of these different contexts as a different microservice, as a different code base with its own lifecycle being built and deployed independently. But DDD also says, well, it's more than that. It's also a boundary for teams. So when we think about how we design a two pizza team and who works on what, the main driven design says that there can only ever be one team working within a bounded context, one team. You can't put two teams in a bounded context. It can only be one. Now, a single team could own multiple bounded contexts. So for instance, a single team might own both online services and web user profiling. But you can't have two different teams within the same context. And this is fundamentally important because what's going on inside of that context isn't just that we're writing software. It's that we're building a shared language about the concepts that live in that context. And as we build shared language, it's really important that we know who's on our team because we're going to be building that language with them. And if we introduce a new team, it's going to start to muddy the language that we're building. And ultimately, that language is going to be implemented and modeled inside of software. And we want our software to look as close to the language that we're using in real life. And this is essentially the idea of shared language. It's nothing more than that. It's just that language inside of the code is also the language that we're using when we're talking to our team. And that language is specific to this context and the team working in that context. So this is it. That's all there is to the bounded context. It's thinking about the different scenarios in which we use a concept and breaking our context out by those scenarios. That's all there is. Now, if you want to learn more about domain modeling, as a theory, there's tons of other patterns. And you've probably seen them and you've probably thought, wow, that's a lot of information. They were first documented on the book here on the left, which is the original Domain Driven Design book. I think for most people who are new to this community, I'd recommend the book in the middle. This is Domain Driven Design Distilled. It was written more recently. It's quite a bit shorter and it's an easier way to grasp these concepts without having to read as much. And if you really want to see the concepts executed in code, then I'd recommend you pick up the book here on the right, which actually looks at all of these patterns in the code. So resources to look at in the future, but we're not going to look at them now. What we're going to do now is look at some patterns that don't require you to pick up a textbook and can show you how to build this shared language concept inside of a bounded context. All right. And again, this is because these tactical patterns, they can help, but they're not required. So we don't want to get bogged down by the jargon. It can often get in the way of actually putting the principles into practice. The first one of these is an architectural pattern called ports and adapters or hexagonal architecture. And this pattern's been around for a long time. Alistair Coburn first documented it I think in 2000 or something like that. I love the gloriously retro graphic that he still has on the webpage describing it. And it's quite a simple concept. All it says is that your application, which here is equivalent to a domain model, right? So it's the model that lives inside of that bounded context. It needs to sit at the center of any app that you build. And then you need to take that business model, and you need to have adapters out to every other part of the world. So if that's the database or maybe an in-memory mock database or a test harness or a GUI or whatever it is, maybe another application or messaging system, it doesn't matter. What's important is to have a bounded wall, a very specific domain model, and then adapters from that model to whatever technology is out there so that you can add and remove those adapters at will. And so if you start to think about what this might look like in a Java project, for instance, this simply means that you'd have a domain model jar that really doesn't have any dependencies in it. Maybe it has some logging, but it certainly doesn't have anything like Spring. It doesn't have anything like a database adapter. This is just pure Java that represents our business model. That's it. And then it also will have interfaces. And the other books that I mentioned earlier, these tactical patterns talk about how to design those interfaces. We're not going to talk about it here. You can follow up on that. But it'll have interfaces that describe what it might mean to store data. It's called a repository pattern. But we won't actually bring in any of those dependencies here. We'll simply write an interface and then we'll code against that interface. And then all of the other adapters that we build, so our database access, maybe for one for in memory and one for an actual database in production, those will be in different packages. So for instance, different jars within the same Maven multi-module project. And those other adapters will depend on the interfaces that we define in the domain model. And then the one last bit is, and this is a bit of advice from me here, is that what you can do is simply have one more adapter, one more package that brings all the other components together and wraps that up. So whether you're deploying your domain with its adapters as a Spring Boot Uber jar, or whether you're deploying that as a war that gets deployed to an application server, or whatever other packaging and deployment model you have, this also becomes an adapter and it will bring in all the other packages as needed. So this is the first pattern. The second pattern starts to look at what code or how code is written inside of that domain model. And I think the word model is overloaded. Everyone sort of knows what that word means, but it's got a lot of different meanings. And so we're not always necessarily saying the same thing. Our context isn't always the same when we use the word model, and even now the word domain model. And so I want to give you just a very practical tip on how to address that fact. The code on the top here used as a pretty standard Java bean type accessor and setter type functions. And this is pretty standard, right? I've got a shopping cart here. I'm going to create a new shopping cart, and I'm going to create a list of items to put in my cart, and then I'm going to create a new item, put it in the list of items, and then I'm going to set that on the cart. This is code you've probably written and seen a thousand times, and it's using the standard accessors that we have in Java beans. The problem with this is it doesn't really operate, or the code doesn't really reflect the model that we were probably using when we talked to domain experts. When we had a conversation about what our domain actually did, we probably talked about adding an item to a cart. But if we look at our code, it doesn't say add an item to the cart. It says create a new list and set those items on the cart. And so already we can see just here in this very basic example that we've got a mismatch between the model we've been using in the English we've been speaking with our team, and the model that's actually operating in the code. And all domain driven design wants to do is to bring this two things together so that the language is shared. And so what we've got at the bottom here is a simple function that we've added to our cart, which is to add an item. And so now when we look at the code, the code reads much closer to the language that we've used with our team. So next project that you're working or even the project that you have now, try getting rid of setters. And if you're going to use getters, have them return immutable data so clients of those objects can't modify the data. And you'll start to see that this forces you to actually add functions that really reflect the behavior of your domain. So one of the key questions after this is how do we figure out what that behavior is? How do we figure out what objects should do inside our domain model? And one of the really exciting things that happened several years back in the domain driven design community is that there was another community called the behavior driven development community that sort of grew as an offshoot from DDD. And what it did is it said, wouldn't it be really nice if we worked with our team using a set of English readable examples, and we turned those examples into test cases that could be run against our software, maybe against that domain layer that we talked about earlier in the hexagonal architecture. And so here I've actually got a feature that looks potentially similar to the one we just discussed. This is the idea of adding an item to a cart here. And if you actually look at the scenario down here at the bottom, it'll say, given that there's a holiday promotion, and it gives a $10 discount to every order, when I add a product to the cart, here it's a PHP t-shirt, then the cart total should be $90 and the discount should be negative 10. But one of the things that we notice here is that in our code in the previous example, we talked about adding items to a cart. We didn't talk about adding products to a cart, but here in this scenario that we worked with our with our product owner, we're talking about adding products. And so again, we can see a discrepancy between the model that we've developed here in a scenario, which will ultimately use a framework like Cucumber or Serenity BDD or any of the many tools in this community to automate this test case. We've got a discrepancy in our language here between adding a product to a cart versus adding an item to a cart. And so this is another practical way that you can write test automation that enforces your requirements and also helps you evolve the language. If you want a detailed guide to this, Goiko Azich wrote a great book called Specification by Example. It's a really easy read and it really walks you through the process here. All right, two other quick patterns here. And these are taken, the screenshot here is from a real project I worked on recently. Chances are that those listening are building REST APIs of some sort today. And hopefully you're using a tool like Swagger or Raml or any of the other contract definition tools to build a human readable specification for your REST API. These are really powerful tools, not just for developers, but also for working with product owners and analysts. And so the picture here is actually from a project I worked on recently where we actually did, we did sprint demos that actually went through our Swagger contract. And our product owners and our analysts actually read through these with us to make sure that the language that was showing up in our REST API matched the language that the team was using when we were at the whiteboard talking about the domain. All right, and the last practical tip that I've got for putting DDD in a practice without having to read a textbook is a technique called event storming. And this is another picture from a project we worked on recently at the Innovation Lab. You can think of event storming as process modeling without any tools and just sticky notes. And it can be a great way to very quickly over a day or two, discover the objects that exist in your domain and start to understand those different contexts. Well, maybe in one context we're adding to our cart and in another context we've got a logistics scenario, whatever they might be. When you get to the whiteboard and you start to put sticky notes up that represent your process, those boundaries start to naturally evolve. And so I've included some links here to blogs that can show you quickly how to do this. It's a really easy activity to pick up. You can give it a try after about 30 minutes of reading and buying some sticky notes. And I've also included some links to some projects we've run recently where you can watch teams go through these exercises and kind of hear from team members themselves on the impact that's had on their projects. All right, so with that I'm going to share this big list of references. These are all the things we talked about today. We'll be sharing these references. I think they've been going out in the chat as we've gone along. We'll be sharing these slides and we'll also be sharing this so you have these links to use in the future. And with that I want to thank everyone for your time. It's been wonderful sharing this with you. And I'll send it back to Burr in the event. We've got some questions. We do have some questions. And Justin, that was absolutely awesome. And the links did go out into the chat. So hopefully people are getting that right now. But one thing that came up was specifically around Karath and specifically OSGI from Maurice. Have you ever looked at OSGI and the concept of modularity from an OSGI standpoint and how does that help you in a domain-driven design model? Yeah, it's a good question. I have worked in those models. And so let's see here, Karath. Karath can be really useful, particularly if you've got complicated class paths and those different adapters might conflict with each other. So I ran into this example the other day where I was using Jboss DataGrid or the Infinisman project and it needed a version of Apache HTTP components that was different than the spring NBC HTTP components under the covers. And so I went through all sorts of crazy gyrations to make those different adapters work within the same model. Karath really helps in those sorts of scenarios, right, where instead of trying to resolve that and do all the testing, we kind of eliminate those with an OSGI more elegant modularity in the class path. But as far as DDD goes, the packaging model isn't so much key to putting these things into practice. OSGI is nice in the sense that it'll enforce more strict boundaries around that domain model versus, you know, my adapter to REST or my adapter to a database. And that's nice. It forces us to think in these ways and separate those concerns. So it can certainly be a great model to reinforce these concepts, but I don't want people necessarily to think that it's a requirement. You can use more or simple packaging tools and achieve the same thing. Another interesting question too, I thought was what is the relationship between event driven design and DDD? And have you explored those concepts and have, you know, how do those worlds come together from your perspective? Yeah, absolutely. So slide number 10. And when I was given the Facebook and Twitter example, is this awesome blog by Martin Kleppmann. And what he does there is essentially explain how that have come out of domain driven design. And I tried not to enumerate these too much here. So we didn't get lost in the jargon. But there's a concept within DDD of the domain event. And it's exactly what you're getting into here. And that led to a pattern called event sourcing and command query responsibility segregation, which sort of came out of the DDD community. But we also got complex event processing from other communities. We got stream processing from more of the Silicon Valley internet company communities. And they're all really tackling the same problem. They're just tackling the same problem from different ways. And so, yeah, you're totally astute for finding that sort of obvious connection there. And absolutely event driven systems can make it much easier to explicitly model the domain. And at the innovation lab where I work, we've spent a lot of time with these. We're a big fan of a tool called Vertex, which Red Hat is providing support for now in our war product. And it's a great way to very explicitly represent the conversations we have at the whiteboard in the code. I'll be doing a Vertex presentation tonight here in Utah. That's why I'm here in Salt Lake City. So we are out of time. But one last comment from Maurice, which I think is important. And he basically says modularity and coding interfaces is absolutely core. And the good news is modularity is king. I think it's in the day. Would you agree with that? Absolutely, absolutely. Okay, well, thank you guys so much for your time today. Thank you, Justin. It was awesome presentation and nicely distills what's going on in the main driven design world. And as always, if you guys are checking us out at the website, you'll see more things coming. We already have the November sessions posted. You'll see some interesting stuff around continuous deployment and some things we're doing at Red Hat for continuous deployment at scale. You also hear from Edson Yanaga, who's written the book on how to migrate to microservices patterns with a monolithic database. You've probably seen that book at developers.red.com as well. But if you have any suggestions for topics you'd like to see, feel free to email me. Most of you probably have my email address right now because I received over 900 PTO events from you guys with the last email blast sent out by marketing. There's a lot of people on holiday, specifically in India, I've noticed and in Germany, it seems. But thank you guys so much for your time. And Justin, thank you. All right. I know.