[0:00] [Music] [0:15] okay everyone it's been great getting [0:22] the middle of you guys [0:23] I'm Andrew Cassell I want to first thank [0:27] all the organizers for putting on HP [0:32] Serbia fantastic conference I'm so happy [0:35] to be here making this horrible noise so [0:39] for those of you who don't know me yet [0:40] I'm from the United States I live in a [0:42] suburb on Washington DC where I'm an [0:46] organizer of the DC PHP Meetup and for [0:51] the last 10 years almost I've been [0:53] writing PHP applications at a company [0:56] called the marine spill response [0:57] Corporation which is a non-profit that [1:00] cleans up oil spills [1:03] I work as a part of a small in-house [1:06] development team with two other [1:07] extremely extremely talented developers [1:10] and I like say that because I think this [1:12] talk may end up on YouTube so in case [1:15] they watch it later but you know we [1:18] build PHP applications that organization [1:21] uses to respond to expose and natural [1:24] disasters so why why are you here today [1:29] what why am I here today and I assume [1:32] it's because we all want to be better [1:33] developers we want to become better code [1:36] craftsmen we want to raise the level of [1:38] our code we want to become a more mature [1:41] developer whether that's go from junior [1:43] to senior from senior and on up we want [1:47] to have a better understanding of [1:48] problems that we're trying to solve we [1:50] want to give a better value to your [1:51] clients to boxers and your customers the [1:55] thing I'm here to talk to you about [1:56] today is domain driven design and it's [2:00] oftentimes called BBD those are you [2:02] don't know it real quick survey who has [2:07] heard about domain driven design DVD [2:09] good quite a bit I'm not going to change [2:11] the slides well I heard [2:13] started but good to hear that a lot of [2:17] you already know where we're going so [2:19] the bulk of the information of this talk [2:21] comes from two books they're oftentimes [2:24] referred to as the blue book and the red [2:26] book I know the color here is a little [2:28] messed up blue book by Eric Evans [2:31] domain-driven design that's like the old [2:33] testament of domain driven design it was [2:36] originally released I think in 2004 and [2:39] it is the it lays the whole plan out for [2:43] domain driven design a little bit later [2:46] von Vernon wrote be implementing [2:48] swimming driven design that's like the [2:49] New Testament and DVD land kind of a [2:53] little more practical and how to apply [2:56] things but I mean since these two books [2:59] have come out there's been many more [3:00] people who have applied domain driven [3:02] design a lot of things have changed so [3:04] there's been more and more books that [3:06] have come out with patterns and [3:08] principles being one that is a very deep [3:10] dive into how to do it and then a lot of [3:13] small cliff notes versions so if you're [3:16] the kind of person who only goes to [3:17] church at Christmas and Easter uses [3:20] probably the books for you all the [3:23] patterns of Anna talked about today are [3:24] not new they've been around for a long [3:26] time [3:27] these are two famous books on patterns [3:31] and software architecture all the talk [3:34] information all this stuff from DVD [3:36] comes from these books for the most part [3:38] and one more thing just to thank Mathias [3:43] Varys and Bo Simonson [3:45] they've been two big proponents of DVD [3:48] and at the HP community [3:49] PHP community and without them I [3:51] probably wouldn't be doing this okay so [3:55] so those of you who have never heard of [3:58] domain driven design or maybe you just [4:00] read the Wikipedia definition BDD is [4:04] about focusing on the core business [4:07] problem that you're trying to solve and [4:09] developing a valuable collaboration with [4:12] other people who hold a stake in the [4:14] success of your products and modeling [4:17] your software in a way that is both [4:19] understandable and maintainable [4:21] now DDD is meant to handle really [4:24] complicated problems like a [4:26] IKEA furniture because what it'll do [4:30] it'll break the domain model down into [4:32] something that's understandable [4:33] and easily maintainable now one of the [4:37] things in domain driven design that's [4:39] very important is object-oriented [4:40] programming if you don't have a good [4:41] understanding of object-oriented [4:43] programming you're not going to go very [4:44] far with it and what I mean [4:46] object-oriented programming I don't mean [4:48] about cars barking or dogs driving which [4:51] we use virtually that usually the first [4:52] thing we learn in the object-oriented [4:54] program which we refer to [4:57] object-oriented programming [4:58] refer to the behavior of the objects not [5:02] just the methods on them so the first [5:07] thing I want to talk about with you guys [5:09] is the first word in domain driven [5:11] design the domain and when I say domain [5:14] I refer to the problem that you're [5:17] trying to solve or the problem space for [5:20] me my domain is oil spill response and [5:23] pencils and chips never like that and I [5:25] don't want to have to tell you all about [5:26] that so for today's example we're going [5:29] to choose something that we all know [5:31] which is a library which I've heard [5:34] still exist they still have books that [5:36] you can take out so let's imagine that [5:39] we're going to build software for a [5:40] library and you know we're obviously [5:44] going to have books in the library so [5:45] we're gonna need a book database a table [5:47] in our database we're going to have [5:49] users so we need a user table and the [5:52] user is in the book the book is going to [5:53] have the going to have an inventory book [5:55] so you're going to have a book inventory [5:57] table and then users are going to take [6:00] out books we're gonna have a book into [6:01] our user link and if you're a symphony [6:05] developer out there you're already [6:06] thinking oh who's going to be the role [6:07] user well that's going to be probably [6:08] the librarian or who can be the role [6:11] advant well that's the librarian or we [6:13] need to solve the problem of logins [6:15] sorting 800 auth and they were going to [6:17] use like he was saying earlier when he [6:18] is no sequel just just stop slow down [6:23] our developer reptile brain that we as [6:28] soon as we hear a problem we immediately [6:29] have a solution before we've heard the [6:32] rest of the problem what is actually the [6:34] problem that needs solving [6:37] so lon not saying that implementation is [6:40] not important but choosing the right [6:43] framer can make a big difference in a [6:45] project but we have to really analyze [6:48] the problem that we're trying to solve [6:49] before we jump right in and start coding [6:54] there's a saying from the jobs to be [6:57] done community that people don't want to [6:59] buy a quarter inch drill they want a [7:02] quarter inch hole people are not paying [7:05] you for your software they're paying you [7:07] to solve their problem what is the [7:13] problem space is your problem actually [7:14] worth solving do people just randomly [7:16] drop their phone no make sure the [7:20] problem you're solve is actually worth [7:21] well to solve in the first place [7:23] you know reminding ourselves that our [7:26] jobs as developers is either to make our [7:29] company a pile of money or save our [7:31] company a pile of money so maybe writing [7:34] our own VI containers writing our own [7:35] frameworks or writing your own session [7:36] management or logins or password resets [7:39] stuff like that is really not important [7:42] what we're being paid for is to focus on [7:45] the core business problems and I think [7:47] that's where a lot of developers need a [7:48] lot more help and getting better at that [7:51] so when I talk to you about common sense [7:54] software development so when I'm talking [7:57] about gdb I'm not talking about the [7:59] patterns of BDD those those are in the [8:01] design patterns books you can learn all [8:03] about that and the whole goal here today [8:06] is not to add a bunch of complication to [8:09] simple problems in one of the first [8:13] pages of the red book von Vernon has a [8:16] table where he lays out whether or not [8:18] you should thinks you should you should [8:19] use BDD or not and I think in character [8:23] kind of paraphrase that with kiss keep [8:25] it simple stupid so if you're doing a [8:27] Content site or brochure site don't use [8:30] domain driven design if you have a [8:32] purely data entry site that's what crud [8:34] is for create read update delete don't [8:37] use it where maybe functional [8:38] programming might work better like a [8:39] communication system if you go overboard [8:43] with some of the things that I'm going [8:44] to tell you about today you end up with [8:46] something like this which is called the [8:47] fizzbuzz enterprises [8:49] which solves the fizzbuzz coding [8:51] challenge and I think about 3,000 lines [8:53] of code just just kind of summarize so [8:59] domain-driven design is not the one true [9:02] way to develop software that is [9:05] obviously Ruby on Rails now all right so [9:11] we talked about you know making good [9:13] software what how do we define what is [9:15] good software well there's been plenty [9:17] of books out there that talked about [9:18] factors in software quality or software [9:21] requirements I'm going to pick what I [9:23] think are the most important five when [9:25] it comes to main driven design and [9:27] that's correctness testability [9:29] usability maintainability and modifiable [9:32] modify ability and I'm going to compare [9:35] a domain driven design app and a crud [9:37] app or is the domain driven design [9:40] community calls as a big ball of mud and [9:42] it's really just a conglomeration of [9:45] code that's all thrown together and [9:47] basically hardly ever works so there's a [9:52] big push in the domain driven design [9:53] community that crud is an anti-pattern [9:55] and the reason why that is the case is [9:59] that and I agree with this quote here [10:02] that a lot of times you know business [10:05] people have given up on developers and [10:06] developers ability to understand [10:08] business problems domain experts as we [10:13] call them you know Lord business here [10:14] the people that we call product owners [10:16] or stakeholders you know someone that [10:18] knows the in and out of the business [10:20] problem and if that's not you maybe if [10:22] you're you know developing something for [10:23] other developers you're the you're the [10:26] domain expert but when we work with [10:30] these people [10:30] we're not just trying to deliver them [10:32] code we're trying to solve their [10:33] problems and to solve their problem [10:35] effectively you have to very well [10:37] understand their problem so when we talk [10:40] to them we need to open our eyes open [10:41] our ears and open our brains up and [10:43] listen if we open the blue book right [10:49] away on page 24 of a 500 page book the [10:53] subject ubiquitous language comes up [10:55] ubiquitous more common across almost [10:59] everywhere you're talking about it so [11:00] ubiquitous language would be common [11:03] between [11:03] developers and the businesspeople [11:07] ubiquitous language is really the [11:09] ultimate power of BDD it's a shared [11:12] language that your development team and [11:14] you're doing and experts agree to speak [11:15] it puts everyone on the same page and [11:18] the power of BDD is understanding the [11:20] business mindset the language and the [11:23] solutions and understanding how to [11:25] implement the business problems in code [11:26] so BDD is not about patterns because [11:32] tools change we switch frameworks all [11:34] the time we switch technology all the [11:36] time it's first about listening it's [11:39] about speaking a common language and as [11:42] we build this common language we're [11:44] going to better understand their problem [11:45] and how to solve it let's take a quick [11:49] example of building that common language [11:52] what is the business or you know the [11:55] organization that you work for call [11:57] they're the people who are using the [11:58] software in the case of a library they [12:01] probably call them clients customers or [12:03] members or employees they probably don't [12:06] call them users but yet every one of us [12:08] probably have a user table or a user [12:10] repository the only people that called [12:12] their people using their stuffed users [12:14] are developers and drug dealers it's not [12:21] that much work to take your code that [12:23] has user and use the word member or [12:25] employee in it it's plain I'm not sure [12:29] if you guys know who David Letterman is [12:31] yeah he's like a cranky old Jay Leno he [12:36] has the famous thing he does in the [12:37] United States it's top 10 list so I'm [12:39] going to give you the top two that's in [12:41] binary reasons programming is hard and [12:45] number one right off the bat gaming [12:47] things that is domain driven design one [12:51] of the key concepts is against that [12:53] ubiquitous language is going to help you [12:55] main things whatever you agree with the [12:57] business people on that's what you call [12:58] it when we look at a crud versus mud app [13:02] and compare that to our DDD app we have [13:05] users we're going to call them members [13:08] something we had like maybe book [13:10] inventory repository what's called at [13:12] the Library catalogue we have strings [13:15] and a crud mud up [13:16] let's create objects that represent [13:18] these things in our in our code it [13:20] becomes much easier to read understand [13:22] and I'm not picking on laravel here but [13:26] if we take a normal credit app we go [13:29] finder sales the object we do somewhere [13:33] queries we we try to find you know books [13:37] that are related to that user this is [13:40] this code if you showed this to a [13:42] librarian they would just feel like WTF [13:45] it doesn't make any sense it's really [13:48] not that much more effort to write code [13:49] that is very very readable so instead of [13:53] a book repository we have a catalog and [13:55] instead of finding the book by maybe [13:57] database idea we use something that's [13:59] more naturally expressive by one by book [14:02] ISBN you know members we have a members [14:04] collection instead of a member [14:05] repository and instead of setting the [14:09] the book relation and attaching it to a [14:13] an array inside of the object we have a [14:16] borrow function on the member they do [14:19] effectively the same thing but in the [14:21] naming becomes much easy to understand [14:23] because now when you go back to look at [14:25] this code five years from now the [14:28] cognitive load that's required is so [14:29] much less it's like when you learn to [14:32] speak a second language like eventually [14:33] you stop trying to think of what is the [14:35] the word for that so what I learned [14:37] German the first time you you know you [14:39] learn library it's bibliothèque but you [14:41] have to think what is the German word [14:42] for library eventually you get faster [14:44] and faster you don't think like that [14:45] anymore you just start to speak in the [14:46] language and that's what this does [14:49] eliminates that translation layer in [14:51] your brain you don't have to try to [14:52] guess you don't have to try to guess [14:54] what this code is doing this kind of [14:58] code tells you what it's doing and it [15:01] offers great encapsulation now I'm not [15:03] saying you break the law of Demeter or [15:05] don't follow solid principles but code [15:08] like this is easier to understand and [15:10] easier to maintain going forward [15:15] now if you've settled on a language with [15:20] your your business people and you're [15:23] trying to form that ubiquitous language [15:24] choose the words that they use for the [15:27] most part that's going to be much [15:28] year to go with what they want but you [15:31] know any one of these is fine there's no [15:33] right or wrong it's really dependent on [15:34] the project you're working on and I'm [15:37] going to guess as developers if you're [15:38] doing be hot testing you're already [15:40] doing this a lot you're already putting [15:42] these verbs in your be hot test so right [15:46] there is your function names right you [15:47] just haven't seen it the whole time kind [15:52] of summarize this thought here I think [15:55] is a great quote but the important part [15:57] is here at the bottom it says programs [15:59] must be written for people to read and [16:01] only incidentally for machines to [16:02] execute because software is incredibly [16:06] difficult to maintain just because it's [16:07] malleable and easily changed making [16:11] something that is easy to read and easy [16:12] to understand we come back to it later [16:14] is probably the most important job we [16:16] have as programmers so if I'm comparing [16:19] the DDD version and the ball of mud [16:21] proud version I'm going to give DDD a [16:23] checkmark in the correctness column [16:25] because it's much easier to make the [16:28] software correct because you can model [16:30] it properly and follow languages the [16:32] business uses and directly translate the [16:34] businesses problems in the language in [16:36] the code [16:44] another topic that's in the kind of in [16:47] the ubiquitous language part of this is [16:49] something called natural identification [16:52] so as developers we often rely on [16:54] primary keys and UID you you IDs the [16:58] business does not think like that a lot [17:01] of things that were you're dealing with [17:02] like let's say this is our library [17:04] example I already have an ID they have [17:06] an ISBN number we should be using the [17:10] numbers that the business you know [17:11] relies on it already has an account ID [17:13] use the account ID that's already unique [17:16] things like that when we're modeling [17:20] this ubiquitous language don't pretend [17:22] it's like the 1800s when you're doing [17:24] this model if you're doing it like say [17:26] an online ticketing system don't pretend [17:28] that people are coming up to a counter [17:30] and buying a ticket no it's ubiquitous [17:32] in the sense that the technology [17:34] influences the language just as much as [17:36] the business problems do it's a two-way [17:38] street because you know as businesses [17:41] evolved obviously you're going to be [17:43] changing a software to match the [17:44] evolving business and as the business [17:47] involves your code needs to evolve with [17:49] it and the language needs to evolve with [17:50] the code as well okay so if you're in a [17:54] large organization and you're supporting [17:56] many teams throughout your company [17:59] there's one more thing I want to tell [18:01] you about ubiquitous language and that's [18:03] that [18:03] when I say ubiquitous it's not [18:04] ubiquitous across the entire universe so [18:07] if you have a marketing department in a [18:08] finance department or sales and [18:10] production you know they make all those [18:13] users or clients or members different [18:15] things and throughout the different [18:17] parts of your system you may want to [18:19] create separate objects in order to keep [18:21] the parts of the code for that part of [18:23] the system separate from the others and [18:25] in one part of the system you might call [18:27] that object a lead or payee or maybe you [18:29] know the production team only cares that [18:31] they're shipping to people so we call it [18:33] a ship - again it's just about naming [18:36] and keeping things separate because one [18:40] of the problems that large code bases [18:41] can end up in is what they call the big [18:43] ball of mud oftentimes that's referred [18:46] to as spaghetti code or shantytown code [18:49] if you don't keep things separate and [18:51] you start calling you know methods all [18:53] over the place you'll have [18:54] so in our library example we're going to [18:58] set up three bounded contexts and that's [18:59] bounded context is that separation of [19:02] concerns within a larger application so [19:06] we'll have a billing section alone [19:07] section which is lending out books in a [19:09] catalog section and we're going to avoid [19:12] you know calling methods and putting [19:15] objects all over the place in our in our [19:18] system because as things grow and we [19:20] would try to make an update to the [19:22] catalog system if that's directly [19:24] depending on the billing system we're [19:26] going to have problems maintaining that [19:29] so what we're going to do when we cross [19:32] these bounded context in these separate [19:34] areas is pass messages and the messages [19:40] we're going to be passing for the most [19:41] private call domain events and I'll get [19:43] into domain events in a little bit here [19:45] but the main thing here is that you're [19:48] passing messages between it whether [19:49] that's an event or you know maybe it's a [19:51] microservices in your passing HTTP or [19:53] less [19:54] either way try to keep your bounded [19:56] context and parts of your system as [19:58] separate as possible as decoupled as [19:59] possible can't stress that enough [20:01] all right so how do we build this [20:04] ubiquitous language well our goal is to [20:07] discover complexity on early on and the [20:09] best process I found for that is called [20:12] events storming now you have to follow [20:14] this process exactly no you don't have [20:16] to especially if you're already an [20:18] expert in the domain probably don't need [20:20] to go through this exercise but I want [20:22] to show you this because I think it's [20:24] the correct manner to think about [20:25] solving software so the first thing you [20:28] need to do is actually meet with the [20:29] people who have the problem that you're [20:31] trying to solve the goal of for essence [20:33] developers is to fully understand the [20:34] problem a bunch of tickets in JIRA is [20:37] not an understanding of a problem what [20:41] we have to do as developers is get out [20:42] from behind our cushy standing desks [20:44] that go up and down and get out in the [20:46] field [20:46] now UX professionals call this [20:48] ethnographic ethnographic research in [20:51] the library example go to the library [20:53] see that they have a terrible windows 98 [20:55] computer running ie6 that's going to [20:57] influence how you write your software so [21:01] what I'm advocating is that developers [21:03] should work directly with stakeholders [21:05] we're going to ask a lot of questions [21:07] we're [21:08] ask a lot of lies they call it the five [21:10] why's so if the librarian says oh we [21:13] need people to borrow books well you're [21:16] going to ask why well because that's how [21:18] our business works and you're gonna ask [21:19] why and keep asking why and why and why [21:22] usually when you get to the fifth why [21:24] usually find out what the actual problem [21:27] is when you meet with these people this [21:32] is what I call you guys know the [21:33] comedian George Carlin is the seven [21:35] dirty words which I'm not going to say [21:36] is this might end up on YouTube but when [21:40] you're meeting with a domain expert do [21:42] not use these words they don't [21:43] understand what an interface in an [21:44] abstract class are what we're trying to [21:46] do here is actually figure out how we're [21:48] going to address the problem get some [21:51] Sharpie markers or some you know a [21:53] whiteboard and some markers don't jump [21:57] right out of the computer we use [21:59] computers you know eight hours a day [22:00] maybe [22:02] compared to the people that are you know [22:03] we're working with we're probably better [22:05] at technology we're faster we can scroll [22:07] through things faster I was in a meeting [22:09] once with one of the guys that I work [22:11] with and he's like he said my eyes are [22:15] rolling back in my head you're scrolling [22:16] through stuff so fast and you know that [22:18] was one of the times I realized that you [22:20] know maybe we're going about this wrong [22:21] and that a you know a low fidelity [22:23] approach like markers or you know [22:25] writing is approachable to anyone [22:27] whether they have any technical [22:28] expertise or not almost anybody can grab [22:31] a marker and draw something now the [22:34] events storming really is about getting [22:36] a huge space and putting a bunch of [22:39] stickies up and the goal here is to try [22:41] to tell a story of how the software's [22:43] going to work we're going to start with [22:45] the events that are in her system in the [22:47] library example a book was borrowed and [22:48] that a book was returned and the reason [22:50] we're doing this is we're trying to [22:51] avoid data modeling we're trying to [22:53] we're trying to model the behavior that [22:55] is in the system not the data eventually [22:59] going to start building out more and [23:00] more of a larger you know diagram you're [23:03] going to have the people involved the [23:05] members that librarians and stuff like [23:07] that those are called actors in events [23:10] storming and you're going to be creating [23:12] commands that go in the system like [23:13] borrow book there's the blue [23:16] there and you know as things get larger [23:21] and larger you'll you'll start to figure [23:22] out the areas that you want to split off [23:24] like maybe the billing context here the [23:27] billing system really doesn't need to [23:28] know much about the book borrowing a [23:31] book landing system we can use the [23:33] messages or events to pass stuff to that [23:35] so we can keep those two separate you [23:39] know if you look at this and maybe an [23:40] event causes something to happen in that [23:42] system so an event will have an event [23:45] listener which will cause a command [23:46] which you know causes to happen in the [23:48] other system it's kind of going through [23:51] the rest of it I mean you can flesh out [23:53] you know your whole story for your [23:57] software eventually you might end up [23:59] with this this giant diagram but this is [24:02] very valuable because you can refer to [24:03] this later when you want to know how [24:06] does our software work like if you're [24:08] trying to read code that may not be [24:09] entirely obvious especially when things [24:12] start firing off events and sending [24:14] messages that becomes kind of decoupled [24:16] and very separate hard to understand [24:17] diagrams like this can be very valuable [24:21] so I'm going to give DVD a double check [24:23] mark in the practice called because you [24:26] know I think the process of building [24:27] your solution is starting with the [24:28] problem and figuring out what is you [24:31] know really the thing that you need to [24:33] do and using a behavior model not a data [24:38] model Martin Fowler he says that doing [24:41] that opposed do the transaction scripts [24:44] that were used to writing is the essence [24:46] of a paradigm shift in object-oriented [24:48] programming so if we want to model this [24:54] the thing that the DVD people call [24:57] domain objects these are the various [24:59] things that are going to be in our code [25:00] these are value objects entities [25:02] aggregates and domain events these are [25:04] primary four types [25:06] the first one is value of objects those [25:08] are the smallest of things in your [25:10] system and those are going to be [25:11] immutable they have no identity things [25:14] in our library example would be a book [25:15] title and amount paid an ISBN number [25:18] very small things [25:20] now contrasting that with some of the [25:22] larger things entities value objects [25:25] have no state they're immutable and [25:26] there's not really much to them an [25:28] entity like a book or a [25:30] Berrien or an invoice has more about [25:33] it's identifiable in the system it's [25:35] mutable things change you know [25:37] librarians change their name it has a [25:39] lifecycle librarians are higher than [25:40] fired enemies will contain the value [25:44] objects like a book entity will have a [25:46] book title or an ISBN number it'll [25:48] contain those value objects and an [25:51] aggregate is just a kind of a fancy [25:53] entity it contains other entities so a [25:57] member may have many books in its [25:59] possession things like that so let's [26:04] start with the value objects there's a [26:05] smallest and easiest to understand look [26:08] at some of these things in the library [26:09] example a book title a Dewey Decimal [26:11] number date borrowed there's are going [26:13] to become objects in our code directly [26:16] so we have a book title class a Dewey [26:19] Decimal number class and the reason we [26:21] do this is not just static typing so [26:23] we're not just doing this for the sake [26:25] of type int a everywhere there's plenty [26:27] of research that will tell you [26:27] statically typed languages don't [26:29] actually help that much when producing [26:32] bug-free code the goal here is that [26:34] we're going to be reducing complexity [26:35] introducing checking throughout the [26:37] system now you have an extra mutable you [26:40] know and PHP objects are passed by [26:42] reference so by making our objects [26:44] immutable we avoid with I consider the [26:46] spooky action at a distance and objects [26:48] where if you pass an object you're not [26:50] guaranteed that that function that you [26:51] called is not going to change that [26:53] object so one of the things that is [26:57] probably the most important aspect of [26:59] domain driven design is that almost [27:01] everything is always in a valid state [27:02] that starts with valid value objects [27:05] value objects are like eggs [27:07] they're the very thin shell around your [27:09] app that is going to solve as many [27:10] problems as possible at the very edge of [27:13] your domain layer so the earlier you can [27:16] handle a problem the less you have to be [27:18] defensive throughout the entire [27:19] application value objects are also a [27:22] gateway drug to test your in development [27:24] if you're not doing test-driven [27:25] development value objects are a great [27:27] way to get started doing test-driven [27:29] development hash tag my tests don't pass [27:34] how do we implement value objects well [27:36] they're just plain old PHP objects or [27:37] popo's as they're called we declare all [27:40] the class properties as private we have [27:43] no setters there's no way to change the [27:45] data that's inside on a value object [27:47] they don't reference anything that is [27:48] changeable like a mutable object and we [27:50] throw exceptions on constructors so they [27:52] can never be an invalid state let's live [27:55] it a simple example like the book title [27:57] business rules for a book title is that [27:59] a book title cannot be empty cannot be [28:01] an empty string we have to have a book [28:02] title that exists let's start with our [28:05] test the first thing we can do is start [28:06] a test and to make sure that you know we [28:08] put in a book title we get a book title [28:10] back out saying value comes out and the [28:12] second one will test that you know if I [28:13] put in an empty book title we expect an [28:16] exception we run our test the class [28:19] doesn't exist yet let's go create it [28:22] first thing we do is just do a simple [28:24] almost like a DTO we put the title [28:26] string in and we get it back out that [28:30] passes our first test that was easy the [28:34] next thing we do is we throw an [28:36] exception the constructor the title is [28:38] empty also very simple and that passes [28:42] our test light is green tests are clean [28:45] we can move on let's run through another [28:48] example date borrowing now to borrow a [28:52] book the the date has to be a valid date [28:56] that's going to be pretty much handled [28:57] by the date immutable class but this [29:00] library system we're just you know [29:01] developing developing it today well I [29:03] know that in my system no date can be [29:06] before May 28th 2017 I can put that [29:09] check in here and if somebody [29:10] fat-fingers the number and put something [29:11] in wrong I can in throw an exception [29:13] because there's no way that somebody [29:14] could borrow the book before or things [29:17] like dates way in the future I've had [29:18] just have many times or somebody types [29:19] in the wrong number and it ends up with [29:21] a year of nine thousand and nine that's [29:23] obviously not the case we can protect [29:25] those kinds of things in our system so [29:28] insert another value object that would [29:30] be in our system like renewals remaining [29:31] so how many times can you renew a book [29:33] to the library again we're protecting [29:37] this class in the constructor by [29:39] throwing an exception if it is in a [29:41] valid state the count goes below zero [29:44] we're going to throw the [29:45] exception now we can put behavior on our [29:48] value objects and they return a new [29:51] value object remember I said there's [29:52] it's not mutable so we can't just [29:54] decrement the count when the decrement [29:56] function is call it returns a new object [29:58] and when you return the new object you [30:00] can guarantee that it's in a valid state [30:01] because the constructor is run so you [30:04] really don't have to look cool check is [30:05] you know they're renewals remaining [30:07] Jesus user have to one your renewals [30:10] remaining you can just call the [30:11] decrement function and then catch the [30:13] exception you don't have to worry about [30:15] it the logic changes it's on renewables [30:17] and things like that it eliminates a lot [30:19] of checking and a lot of if checks [30:20] throughout your entire code base let's [30:23] go to one more example hopefully this [30:25] will you know just to kind of solidify [30:27] this you can use value objects that are [30:30] composites of other value objects so [30:33] like a loan period for a book start date [30:35] and end date you can pass the value [30:37] objects that we created earlier in the [30:39] constructor and guess what you have to [30:41] don't have to do any checking I know [30:42] that if it's a date borrowed it's a [30:44] valid date I know if it's at they do [30:46] it's a valid date renewals remaining I [30:48] know they have renewals remaining [30:50] because it couldn't be a negative one [30:51] here it's already been validated it's at [30:53] least a zero or one then I do a little [30:56] bit of a check here to make sure that [30:57] you know the start date isn't before the [30:59] NBA tour after the end date or you know [31:01] whatever vice-versa [31:02] and if that's not a valid condition we [31:05] throw an exception so now I can pretend [31:07] I can depend on this loan period always [31:10] being in a valid state throughout my [31:11] entire application and I can do things [31:13] like math on it stuff like that if I [31:15] want to extend the loan by two weeks I [31:18] can write a little simple function [31:19] extend by two weeks and it you know [31:22] takes the date borrowed adds two weeks [31:24] to the date that it's due and return I [31:28] mentioned earlier that you know your [31:31] behavior that's on the renewals [31:32] remaining decrement function that's [31:34] going to protect this so if somebody [31:36] doesn't have any renewals left you don't [31:38] have to check other renewals remaining [31:40] first before we extend the loan by two [31:43] weeks it's automatic I would throw an [31:46] exception you catch the exception say oh [31:48] this person can't renew this it's a [31:50] completely different way of thinking [31:51] about doing code so in gdb you know we [31:56] have things like book title [31:57] condition ISBN and cred mud most people [32:00] are just using strings dewey decimal [32:01] number would be an example in a library [32:03] probably just a float so for DVD verses [32:08] the ball of mud crud the testability is [32:10] much much higher the maintainability is [32:13] a lot higher and i think your code is [32:15] far less brittle if you're using value [32:17] objects if you don't take any of the [32:20] advice I give you this talk using value [32:24] objects in places that it matters will [32:26] make a big difference in your code [32:27] because you know let's face it we don't [32:30] all test everything so what are entities [32:36] well entities like I said is anything in [32:38] your system that is going to change over [32:40] time like a librarian or a library may [32:42] change his name a book a book could you [32:44] know get destroyed so it might have [32:46] state in the sense that you're going to [32:47] track it a lifecycle entities in are [32:52] identifiable they have an ID like the [32:53] ISBN number for a book may be a member [32:55] ID or an account ID they have state in [32:58] their mutable you can change them but [33:00] again just like the value objects we're [33:01] going to try to keep your entities never [33:03] in an invalid state so everything is [33:05] going to be always valid throughout the [33:06] entire system they're going to again [33:08] operate on those value objects we're [33:11] going to try to avoid putting security [33:13] and permission checks inside of our [33:15] entities and the last thing is going to [33:17] try to do is make them storage agnostic [33:19] and that can get a little bit [33:21] complicated but usually most people use [33:23] doctrine annotations to do that let's [33:27] look at an example of an entity [33:29] hopefully you guys can see that in the [33:31] back but if we have our book class you [33:34] can see just like that composite value [33:36] object all we do is pass the other value [33:38] of the kind of a constructor and we no [33:40] longer have to validate that the book [33:41] title is not empty and the ISBN number [33:43] is valid in the book condition is valid [33:45] and the last thing is we just generate a [33:48] UUID inside of the entity to create the [33:51] unique ID for that entity if you guys [33:55] are using like active record pattern or [33:57] MS that you know use data arrays things [34:00] like that you're going to be able to by [34:03] passing those objects into the [34:04] constructor you avoid that check you [34:06] don't have to constantly have this you [34:08] know check for empty every everywhere [34:10] throughout your system the getters on [34:15] these entities are going to return at [34:16] value objects so if you have a get book [34:19] condition a good book title those should [34:21] return the value objects let's look an [34:27] example of how to store these in a [34:29] relational database using doctoring so [34:32] we had the constructor for the book [34:33] which has the book title ISBN and book [34:35] and it's book condition what most people [34:39] end up doing in PHP is using doctrine [34:41] annotations or the doc doctrine why yeah [34:43] a file or other ways of setting up [34:47] doctrine but you're just going to store [34:49] those you know in the database now the [34:54] easiest way to go through doctrine is [34:55] the store two strings doctrine does have [34:57] something that's called embeddable which [34:59] lets you actually store the value [35:00] objects directly but that can get a [35:03] little bit messy when it goes a little [35:04] bit too far so i recommend like casting [35:07] all these variables to string and then [35:08] getting that back out but that's it's [35:10] not that bad I'm sorry but the biggest [35:13] thing I want to bring to you from [35:16] ubiquitous language and to your energies [35:18] is that senators are bad okay we don't [35:21] want to have set-set-set-set everywhere [35:24] I'm not going to pick on propell is [35:26] there a fine oral but the problem with [35:28] using an ORM is we say new book set [35:31] title set price you know set author all [35:34] this stuff and this kind of code becomes [35:37] hard to maintain over time because at [35:40] what point is the book in a valid state [35:42] when we say the new book it's not valid [35:45] yet because it doesn't have a title [35:46] where we haven't set the price yet it's [35:49] not till all the way down in the code [35:50] where you call save that makes it [35:53] incredibly difficult to test the only [35:56] thing here that's really protecting this [35:57] possibility are the database constraints [35:59] and it's really hard to do database [36:00] constraints like a date not after May [36:03] 28th 3007 it becomes incredibly [36:06] difficult to try and do or impossible [36:10] again and put behavior on our entities [36:13] that actually makes sense for the domain [36:14] so if a librarian needs to look at a [36:17] book and say that this book has been [36:18] damaged maybe we have a degrade function [36:21] for [36:21] creating the condition of the book or [36:23] damage function that marks that has [36:24] damaged again don't don't use setters [36:27] because that just loses the ubiquitous [36:30] language or the understanding that you [36:31] have in your domain aggregates so I [36:36] mentioned aggregates are a fancy kind of [36:37] entity they manage child entities and [36:40] they form a transaction boundary in a [36:42] database examples of an aggregate in the [36:45] library example would be a member [36:47] because they're going to contain books [36:49] they are going to have books in their [36:50] possession if you have invoices in your [36:53] system that's a great example of an [36:54] aggregate because an invoice contains [36:56] line items things that are entities that [36:59] could change on their own that are then [37:00] contained by the aggregate so in our [37:04] aggregates we're going to take language [37:06] directly from our domains if you look at [37:09] the top left we have the member [37:11] borrowing a book so pretty easily we're [37:15] going to have a borrow function where [37:17] you pass a book to it and just for now [37:19] let's say that it just puts the book in [37:21] the array and using like you've [37:23] mentioned earlier horrible doctrine [37:24] annotation that can automatically be [37:26] stored in the database if you want to [37:29] put some logic in your aggregates and [37:31] your entities that's that's great you [37:34] know if we want to limit the number of [37:35] books that somebody can borrow to five [37:37] we can build that right here in the edit [37:40] e we don't have to do the checking [37:41] outside so if somebody goes to borrow a [37:43] book and they already have five books [37:44] borrowed which are an exception and [37:46] catch the exception if the logic behind [37:50] borrowing and how the limit stuff like [37:52] that maybe this isn't the greatest [37:53] example but if that became complex feel [37:57] free to use a specification special [37:58] education pattern is a well-known [38:01] pattern and here you can guard for these [38:03] things and try to protect that by using [38:05] external classes that you bring in and [38:07] the reason you do this is for testing [38:10] it's a lot easier to test the book [38:13] borrowing limit specifications by itself [38:15] then trying to test it while you're [38:17] trying to test the entity and I [38:19] mentioned that entities are aggregate [38:22] roots form a transaction boundary that [38:26] is really just you know and when it [38:28] comes to database if you're going to [38:29] store a member you make changes to a [38:31] member everything that goes along with [38:33] that member is going to be stored in one [38:34] transact [38:35] if you have another aggregate it's [38:37] another member that's going to be maybe [38:38] a separate transaction if it works out [38:40] like that but the whole idea is of these [38:42] these aggregates are atomic and that [38:45] they're consistent all the time never [38:47] invalid state so you know we talked [38:53] about value objects and aggregates and [38:55] entities in all this ubiquitous language [38:58] what this boils down to is not only [39:01] better code more easily you know easily [39:03] read easier to maintain I think it's [39:06] also going to improve user interfaces [39:07] because if you're doing crud apps a lot [39:10] of times when you design a crud app you [39:13] follow the cred patterns where you're [39:14] creating adding creating and reading and [39:17] updating deleting so you end up with a [39:19] table of things like borrowed books and [39:20] you have edit and delete now when a [39:23] librarian comes to your software here to [39:25] use this she's not thinking I'm going to [39:27] come to the borrowed books [39:28] part and delete a book it's it's not [39:31] returning a book is not deleting a book [39:33] or editing a record for the loan date [39:35] you know this ubiquitous language and [39:39] this event storming you know figuring [39:41] out this language kind of forces you [39:43] down [39:44] having buttons that match the functions [39:46] that are on your objects so you know if [39:48] you have a borrow function on the member [39:50] you're probably going to have a button [39:52] that says borrow a book and this is [39:54] called a task-based interface and it is [39:56] a far better way to design user [39:58] interfaces compared to what they call [40:00] this which is the programmers interface [40:02] which is understandable only to [40:03] programmers so I'm going to give DDD a [40:08] check and a usability column because I [40:10] think it's makes software that is both [40:12] easier to use so people using it and for [40:14] the developers to develop now one of the [40:18] things I haven't mentioned yet that I [40:19] think is very important on every app is [40:21] security and domain-driven design when [40:24] they talk about security they talk about [40:26] taking a layered approach and when they [40:28] say layer they don't mean the [40:29] traditional you know layers going down [40:31] we talk about this fancy term called [40:33] hexagonal architecture and what it is is [40:37] it's kind of a fancy way of doing [40:38] layered architecture it's highly [40:40] dependent on the dependency inversion [40:41] principle that high-level modules should [40:43] not depend on lower-level modules and [40:45] that both should depend on [40:47] so when you're moving between layers in [40:50] your system you're using abstractions [40:51] and interfaces so your object literature [40:55] down your business domain have no idea [40:58] how to render themselves that everything [40:59] is patched up through an interface so [41:02] the goal here is not to avoid tying [41:05] everything together to keep things be [41:07] coupled to keep them loosely coupled if [41:10] you notice this red layer on the outside [41:12] is very thin and there's a reason for [41:15] that because frameworks should not be [41:20] part of your core logic they are [41:22] something that is separate code [41:24] maintenance becomes very difficult now [41:28] if you've watched the office space movie [41:29] and you realize at some point you just [41:32] want to do construction work because [41:34] maintaining a legacy code base and cud [41:36] and it's all tied to the framework and [41:38] you have to do an update makes you when [41:40] I just quit you know I've I'm 33 years [41:43] old and hopefully I have another 33 [41:45] years of development in front of me I [41:48] have no reason to you know assume that [41:51] I'm going to stop but I feel like you [41:53] know I spent I spent the first few years [41:55] as a developer digging my own grave [41:57] as I was chugging out crud code I had [42:00] built it you know we our team built a [42:02] large application and we're now trying [42:04] to support and please take my advice and [42:07] try to develop much more maintainable [42:09] code than I did because you know it [42:11] becomes a huge burden because your [42:14] frameworks you know are on a release [42:15] schedule of twice a year say for [42:17] symphony or laravel you know whatever [42:20] they feel like and I guess but you know [42:24] that framework is changing all the time [42:26] and you don't want to have your domain [42:27] logic tied to that framework and have to [42:29] change your domain logic with it every [42:30] time so you know important to keep that [42:33] separation you know I'm hoping that the [42:35] domain logic I'm writing today could [42:37] last 10 20 years I'm sure we're going to [42:40] change frameworks five six times in that [42:41] amount of time just technologies go so [42:43] fast I want to mention two great talks [42:46] by Matias Farias [42:47] and uncle Bob Martin first decoupling [42:51] the model from the frameworks gave it [42:52] leaner con that's on YouTube and then [42:54] Ruby Midwest architecture the last years [42:57] by Uncle Bob [42:59] to watch those talks they're fantastic [43:02] so many DVD practitioners recommend very [43:06] thin controllers pad soft commands to [43:08] command bios and application services [43:10] I'll get to those in a minute [43:12] but when I want to mention real quickly [43:15] here is that following solid if you have [43:18] heard the solid principles and you know [43:21] having good clean code and depending its [43:25] dependency inversion things like that [43:26] that are very important that really [43:28] really matters in the center section in [43:29] your domain your business logic it's [43:31] important to keep that pure and that [43:33] separate from the framework and very [43:35] well architected the outside edge the [43:37] framework code your controllers I think [43:40] you save a lot of time by you know [43:42] treating it like a wild wild west just [43:44] get the job done in the controllers but [43:46] that relies on solid well tested [43:48] business logic you'll be able to move [43:49] much faster so you know I think the [43:53] hexagonal architecture and qicang accord [43:56] with the domain business logic separate [43:59] from the frameworks is a much better way [44:01] to maintain software going forward so [44:03] when you give the check mark and [44:03] maintainability so if you want to look [44:07] at you know how do we keep this software [44:09] modifiable one of the best ways I know [44:11] is using debate events and domaine [44:14] events are part of the core domain in [44:15] that center section in that exokernel [44:16] architecture these happened in the past [44:19] they're probably important enough to [44:21] record so we're going to we're going to [44:22] persist those to the database they're [44:24] important enough to other parts of the [44:26] system so we going to pass them around [44:27] my messages they are immutable value [44:29] objects just like everything else with [44:31] the other value knowledge that I talked [44:32] about earlier they do not contain [44:34] entities or other mutable objects just [44:36] like the other valuable objects and if [44:38] you want you can create them in entity [44:39] and I'll show you how to do that alright [44:42] so let's look at the first one first [44:45] event here at the bottom on the Left [44:47] book was borrowed we use that as an [44:49] example of an event so like I mentioned [44:52] an event is a value object there very [44:54] simple we have the value objects pass in [44:57] a constructor we know everything is [44:59] valid here there's no checking to do now [45:01] it's the name of it book was borrowed [45:03] that's meant because it was in the past [45:05] tense [45:06] obviously you don't have an event until [45:08] somebody does something in a system and [45:09] when you're publishing it it's already [45:11] having the pass [45:12] there's no setters on these again [45:14] they're immutable and if you're going to [45:16] persist this there's one little thing [45:18] you have to do and that's just add an ID [45:20] to it and then you can use your docket [45:22] annotations things like that if you're [45:23] not going to persist it you don't need [45:24] an ID now let's take a little bit more [45:28] complex example here this is our flow [45:31] chart for the book lending context and [45:36] let's assume that somebody has damaged a [45:40] book and we're going to remove it from [45:41] circulation so that's that bottom event [45:43] we're going to create an event called [45:45] damaged book was removed from [45:46] circulation and bring that up a little [45:48] bit bigger now I know this looks like is [45:50] a really big long German word but it [45:53] describes what is happening what has [45:55] happened in the past don't be afraid of [45:57] long class names if you if you need more [46:00] words to describe something use more [46:01] words if you need less words these less [46:03] words but I can't overemphasize enough [46:06] that if you just call this you know [46:07] damage book you don't know what is you [46:11] know actually happened you know as the [46:12] book damaged we move be very very [46:14] specific when you're naming your meds so [46:17] if we're in the you know place we're [46:19] going to charge a fine for that number [46:21] remember I mentioned having separate [46:22] bound in context or alone system and our [46:24] billing system we're going to put in [46:26] what's called a listener or a subscriber [46:28] in that partion of the code will listen [46:30] for that event to be published and you [46:32] know we're going to have very ubiquitous [46:35] language sounding functions like charge [46:37] fine on member and then we're going to [46:40] publish the if that member was fined if [46:44] you're using Doc's from an entity [46:45] manager you're going to flush your [46:47] domain model to the database before you [46:51] fire the event we're using to do that is [46:53] so other things in the system can again [46:56] read that data off the database but more [46:58] importantly if you ever decide to change [46:59] your architecture later and because your [47:01] system grows and you need to move from [47:03] your events to being immediately [47:04] published to a queue you no longer have [47:07] to worry that your data is not being [47:08] persisted before the event is fired off [47:10] to the queue so this last line of this [47:16] function here is what we're gonna attack [47:18] next is publishing the event inside the [47:20] listeners the [47:23] we do something which is called [47:25] recording events or event recorder [47:27] basically the the object is going to be [47:29] responsible for tracking the events that [47:30] happen inside we can easily fire the [47:33] events inside of the entities and I use [47:36] a trait throughout the system called a [47:38] vent recorder and all that does is track [47:40] an array of events that happened the [47:42] object as the object is mutated so by [47:45] doing this we don't decoupled the fact [47:48] that member entity is creating these [47:50] events very easy to see that if you look [47:53] at the member class the events that are [47:54] generated or inside that entity so on [47:59] the outside this was a controller or a [48:01] listener or whatever your last line of [48:04] everything is just going to be whatever [48:05] the entity is get recorded event that's [48:07] just like a good way of knowing that [48:10] everything is working and everything has [48:12] been published throughout the entire [48:13] system so using an event using something [48:17] like that instead of calling functions [48:18] throughout different parts of the system [48:20] I think makes your code much more [48:21] modifiable I give the check to that now [48:25] when I cover two topics in domain driven [48:26] design that somehow I've gotten really [48:28] really mishmash and DVD but I don't if [48:31] you go and read stuff about DVD you're [48:33] going to immediately see these two [48:34] things and that's command query [48:36] responses segregation secure us any [48:38] other one is event sourcing now CQRS is [48:42] it sounds like a complicated concept [48:44] concept but it's it's not really that [48:46] complicated what we're going to do is [48:48] we're going to take our arc software and [48:50] our code when we split it in two [48:51] sections one for rights and one for [48:54] reads and when we see like the rights [48:56] ray is really talking about models so [48:58] we're in have a write model and that was [49:00] the entity as an aggregate of things [49:01] like that that I've been showing you and [49:02] the read model and the read model is [49:05] probably maybe just repositories and [49:06] arrays it really doesn't matter do that [49:08] however you want because that's mostly [49:10] going to be used for reporting and views [49:12] and things like that that don't really [49:14] aren't really business logic or are not [49:16] core to the domain the read models [49:18] probably change much more frequently so [49:20] I change by having your code split [49:22] between a domain model on the right side [49:24] and a read model on the read side as the [49:27] read model changes more frequently you [49:28] don't have to make changes as a main [49:30] model and more complicated business [49:31] logic [49:34] Yeah right was the domain model so how [49:37] it is like CQRS work just kind of like [49:39] as a high level thing well if you're [49:42] used to having controllers that do [49:44] everything we're in a split kind of [49:45] where everything happens into a separate [49:47] section called a command bus and the [49:49] command bus is going to have many [49:50] handlers so if you used to event [49:51] publishing it's like having an event [49:53] publisher and many things listening to [49:55] it that that's really what it's going to [49:57] happen so as a request comes in the [50:00] controller all it has to do is figure [50:01] out that request becomes this command so [50:04] you know if you're using Symphony and [50:06] you've defined your route your [50:08] controller method becomes like one or [50:10] two lines you're just figuring out okay [50:12] this is a member or a book route all I [50:15] have to do is generate a book was [50:16] borrowed command and fire that to the [50:18] command bus so our command is again [50:21] another value object an immutable value [50:24] object just like the other ones there's [50:25] no centers on this and they're very very [50:27] simple to create usually it's just IDs [50:28] not too worried about entities at this [50:30] point so your controllers become super [50:34] super spin very very easy to modify [50:36] so that controller figures out the [50:38] command it creates that object and it [50:40] publishes it to the command block and [50:42] the command bus all it has to do is [50:44] figure out which command handle or do I [50:46] pass at you so let's lay passes to that [50:48] now usually what happens is that a [50:51] command figures out a response and maybe [50:53] that gets piped up to the controller but [50:56] if you're already at this point of doing [50:57] secure arrests you're probably doing [50:59] something that's very complex so that [51:01] might not be the case maybe you're doing [51:03] Ajax polling or something like that so [51:06] you know don't say that every command [51:08] hailer is going to return a response if [51:10] not answer the gate the goal here is to [51:12] make sure that our controllers are super [51:13] super thin so that one line controller [51:15] is going to be very very important when [51:17] I mentioned that we're trying to [51:18] separate our code from our framework [51:20] because now when Simpson your laravel [51:23] changes a way to do routing with [51:24] controllers it's it's very easier just [51:26] moving one line to another function call [51:29] I'll put the slides up on line but on a [51:32] put a link to this article here it's a [51:34] great description of CTS using human [51:36] command bus but I want to caution you [51:38] that not every problem just like I was [51:40] mentioning earlier in the beginning to [51:41] talk not every problem needs CQRS and [51:43] event sourcing an event by my command by [51:46] this is a diagram I made [51:48] work trying to describe what this [51:50] architecture was going to look like and [51:51] it got kind of complex I didn't think it [51:53] would at first but yeah there's a lot of [51:57] complexity a lot of classes to [51:58] implementing this so you know be [52:00] cognizant of that so really for [52:02] complicated problems the last thing I [52:11] want to talk about in DDD is event [52:14] sourcing now there's anybody here play [52:16] chess a couple people [52:18] all right so chess matches can be [52:22] described by a list of moves you can [52:24] read if you know how to read the [52:25] notation you can replay a chess match [52:27] the almost ending chess match that has [52:29] happened in the last couple hundred [52:30] years is available in this notation if [52:34] you go to your bank they're not tracking [52:35] your balance at each you know by setting [52:38] your balance in a database table to [52:40] tracking every transaction throughout [52:43] the system that's how your balance is [52:44] calculated as developers we're used to [52:47] get no we use get and if you know the [52:51] internals of get it's not storing every [52:52] copy of every file you have it's during [52:54] owning the changes that's the gist of it [52:56] event sourcing is that we're only going [52:58] to change store the changes that happen [52:59] entities over time we're not going to [53:01] store the whole estate of the entity [53:02] what are the advantages of using event [53:05] sourcing versus using normal relational [53:07] models now he mentioned earlier the [53:09] object-relational impedance mismatch you [53:11] basically can avoid that through event [53:13] sourcing you avoid writing a lot of data [53:15] mappers which a lot of developers hate [53:17] reduces the table count so if you have [53:19] members and/or sleep maybe the invoice [53:21] example is easier if you had invoices [53:23] and line items and shipping addresses [53:24] and taxes and things like that your [53:26] story you end up basically down to two [53:30] tables one is an invoice like ID and the [53:34] other table is all of your events so [53:36] we're not going to store the the project [53:38] properties of the object that database [53:40] we're going to store the events or in [53:42] persist them an append-only storage that [53:44] becomes you know quite easy to do it's [53:46] basically an array in event so if you [53:48] create an object when you push in array [53:49] an event but when we have our methods [53:53] that we're talking about earlier earlier [53:54] like borrow like the ubiquitous language [53:56] method of borrow a book all that becomes [53:58] is applying the ascent to the object so [54:01] if you put the book was borrowed event [54:04] in the history of that object if you [54:06] were to replay that history of that [54:08] object you would not you would know that [54:09] that book was borrowed so it's a way to [54:11] be couple your entity is even further [54:14] from the storage so it can be an [54:15] agitation to that again just like the [54:18] seeker s it's a little bit more [54:19] complicated so I don't advise it for [54:20] every project there's a couple of [54:23] libraries that will help you do event [54:25] sourcing easier and I'll put those there [54:28] on the slide sequence iam people learn [54:31] more you know all the books are out [54:33] there there's a great group of guys that [54:36] did it and ladies that did a dev book [54:38] club they went to the red book chapter [54:40] by chapter and talked about it a couple [54:42] of great podcasts that podcast will [54:45] stack Radio Elephant Room I'll talk [54:47] about domain-driven design the [54:48] domain-driven design conference from [54:50] Europe posts all of their videos and [54:51] talks online at least most of them and [54:54] they're all fantastic to watch if you [54:56] want more of a workshop there's an ID DD [54:58] workshop which is done by the guy who [55:00] authored the red book there's a github [55:03] repository that's a state of the union [55:05] that you know great things are happening [55:08] in GED and there's a Google Group out [55:12] there that is absolutely fantastic [55:13] there's tons of information on there but [55:16] all those things are getting in the [55:17] slides you guys can go find them I want [55:19] to leave you with one more thing in [55:20] domain-driven design and if you've ever [55:23] heard of this it's called the manifesto [55:25] for agile software development it's at [55:27] agile manifesto org what I mean agile I [55:30] don't mean you're a drow I mean actual [55:32] make software that has developed in an [55:34] agile manner meaning it's responding to [55:36] change they have a couple of you know [55:40] key tenets that they promote and they [55:42] say individuals and interactions now are [55:45] over processes and tools for me for [55:47] domain driven design that means meeting [55:49] with domain experts in building a [55:50] liquidus language not trying to do out [55:52] you have all diagrams and things like [55:54] that working software the need we don't [55:57] need documentation and software is easy [55:59] to read just like that code that I [56:01] showed you earlier you don't have to try [56:02] to decipher it is easy to read customer [56:05] collaboration again that's building that [56:07] ubiquitous language and not trying to [56:09] you know do spec after spec at respect [56:11] with respect to try to find your [56:13] software build that [56:14] event storming session build with the [56:16] software supposed to do that becomes [56:18] your spec and responding to change [56:20] that's easily modifiable code code that [56:23] is a couple from our frameworks code [56:24] that uses the main events that passes [56:26] messages and is easy to couple you know [56:28] I think following some of the practices [56:30] of DDD if they don't do everything that [56:31] I talked about today will make your [56:34] software much more agile you'll be much [56:35] more successful and hopefully make way [56:38] more money so the talk is on joined in [56:41] if you'd like to rate it I copied some [56:42] of these topics I didn't really leave [56:44] time for questions but I am happy to [56:46] answer questions later on the lobby or [56:49] over a beer so thank you [56:50] [Applause] [56:56] [Music] [56:56] [Applause] [57:03] [Music]