[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:17.54,0:00:19.74,Default,,0000,0000,0000,,ERIC ROBERT: All right, hi. I'm Eric Roberts Dialogue: 0,0:00:19.74,0:00:21.43,Default,,0000,0000,0000,,and I'm here to talk to you all about Dialogue: 0,0:00:21.43,0:00:23.22,Default,,0000,0000,0000,,how you can use software design patterns Dialogue: 0,0:00:23.22,0:00:24.94,Default,,0000,0000,0000,,to put your Rails app on a diet Dialogue: 0,0:00:24.94,0:00:29.32,Default,,0000,0000,0000,,and make your tests run really, really fast. Dialogue: 0,0:00:35.70,0:00:38.32,Default,,0000,0000,0000,,Jokes aside, we will be telling you about\Nsome Dialogue: 0,0:00:38.32,0:00:41.61,Default,,0000,0000,0000,,design patterns. Not so much making your tests\Nrun Dialogue: 0,0:00:41.61,0:00:44.56,Default,,0000,0000,0000,,fast. But we're here to talk about domain-driven\Ndesign Dialogue: 0,0:00:44.56,0:00:46.54,Default,,0000,0000,0000,,hexagonal architecture in Rails. Dialogue: 0,0:00:46.54,0:00:48.79,Default,,0000,0000,0000,,I'm Eric Roberts. I'm a software developer\Nand I Dialogue: 0,0:00:48.79,0:00:52.51,Default,,0000,0000,0000,,work at a company in Waterloo, Ontario, Canada\Ncalled Dialogue: 0,0:00:52.51,0:00:56.57,Default,,0000,0000,0000,,Boltmade. I met Declan when we worked together\Nat Dialogue: 0,0:00:56.57,0:01:00.15,Default,,0000,0000,0000,,PrintChomp. Before that, I was a frontend\Ndeveloper for Dialogue: 0,0:01:00.15,0:01:02.94,Default,,0000,0000,0000,,a number of years, and I'd worked around Rails Dialogue: 0,0:01:02.94,0:01:06.43,Default,,0000,0000,0000,,applications, but mostly at the view layer\Nuntil Declan Dialogue: 0,0:01:06.43,0:01:09.68,Default,,0000,0000,0000,,dragged me kicking and screaming into backend\Ndevelopment and Dialogue: 0,0:01:09.68,0:01:12.47,Default,,0000,0000,0000,,made me care about stuff like we're talking\Nabout Dialogue: 0,0:01:12.47,0:01:13.83,Default,,0000,0000,0000,,today. Dialogue: 0,0:01:13.83,0:01:15.89,Default,,0000,0000,0000,,And this is the biggest crowd I have ever Dialogue: 0,0:01:15.89,0:01:17.93,Default,,0000,0000,0000,,presented in front of. So if you'll excuse\Nme, Dialogue: 0,0:01:17.93,0:01:20.42,Default,,0000,0000,0000,,I need to take a picture and email my Dialogue: 0,0:01:20.42,0:01:21.25,Default,,0000,0000,0000,,mom. Dialogue: 0,0:01:21.25,0:01:26.82,Default,,0000,0000,0000,,DECLAN WHELAN: OK. Hi everybody. Real pleasure\Nto be Dialogue: 0,0:01:26.82,0:01:29.32,Default,,0000,0000,0000,,here. My name is Declan. I'm the co-founder\Nof Dialogue: 0,0:01:29.32,0:01:33.32,Default,,0000,0000,0000,,a company called PrintChomp, and my story\Nis about Dialogue: 0,0:01:33.32,0:01:36.53,Default,,0000,0000,0000,,two years ago, I had a opportunity to launch Dialogue: 0,0:01:36.53,0:01:38.63,Default,,0000,0000,0000,,PrintChomp, and I was looking at technologies,\Nand I Dialogue: 0,0:01:38.63,0:01:41.03,Default,,0000,0000,0000,,decided that Ruby on Rails was really the\Nbest Dialogue: 0,0:01:41.03,0:01:45.11,Default,,0000,0000,0000,,platform for us. The only challenge was that\Nneither Dialogue: 0,0:01:45.11,0:01:47.88,Default,,0000,0000,0000,,me nor anybody on my team knew Ruby nor Dialogue: 0,0:01:47.88,0:01:48.96,Default,,0000,0000,0000,,Rails. Dialogue: 0,0:01:48.96,0:01:52.17,Default,,0000,0000,0000,,So it was kind of a brave, maybe, decision, Dialogue: 0,0:01:52.17,0:01:54.71,Default,,0000,0000,0000,,but it's one that I don't regret. And one Dialogue: 0,0:01:54.71,0:01:56.59,Default,,0000,0000,0000,,of the things that drew me to the community Dialogue: 0,0:01:56.59,0:01:58.95,Default,,0000,0000,0000,,was the fact that, or, to the platform, was Dialogue: 0,0:01:58.95,0:02:05.26,Default,,0000,0000,0000,,the community around sharing, around the openness\Nof, of, Dialogue: 0,0:02:05.26,0:02:08.38,Default,,0000,0000,0000,,of sharing code and, also, a lot about, about Dialogue: 0,0:02:08.38,0:02:12.50,Default,,0000,0000,0000,,the test-focus, which has been pretty important\Nto me. Dialogue: 0,0:02:12.50,0:02:14.32,Default,,0000,0000,0000,,But the cool part, I think, about it, was Dialogue: 0,0:02:14.32,0:02:16.70,Default,,0000,0000,0000,,we intentionally took on a lot of technical\Ndebt, Dialogue: 0,0:02:16.70,0:02:18.80,Default,,0000,0000,0000,,because I knew that, I knew that I would Dialogue: 0,0:02:18.80,0:02:20.44,Default,,0000,0000,0000,,not know enough about our domain. It was a Dialogue: 0,0:02:20.44,0:02:22.34,Default,,0000,0000,0000,,new domain for me, printing, and I also did Dialogue: 0,0:02:22.34,0:02:24.79,Default,,0000,0000,0000,,not know enough about Ruby. I did not know Dialogue: 0,0:02:24.79,0:02:28.96,Default,,0000,0000,0000,,about, enough about Rails. So, very intentionally\Ndecided to Dialogue: 0,0:02:28.96,0:02:30.100,Default,,0000,0000,0000,,do our best, the best that we could, knowing Dialogue: 0,0:02:30.100,0:02:33.16,Default,,0000,0000,0000,,that we would end up, very likely, with a Dialogue: 0,0:02:33.16,0:02:36.25,Default,,0000,0000,0000,,pretty heaping mound of technical debt. Dialogue: 0,0:02:36.25,0:02:39.60,Default,,0000,0000,0000,,And that turned out to be true. And has Dialogue: 0,0:02:39.60,0:02:43.98,Default,,0000,0000,0000,,anyone had that experience? I don't know.\NYeah. So, Dialogue: 0,0:02:43.98,0:02:45.63,Default,,0000,0000,0000,,but recently we had an opportunity to build\Nan Dialogue: 0,0:02:45.63,0:02:47.85,Default,,0000,0000,0000,,API, and that was really exciting for me.\NAnd Dialogue: 0,0:02:47.85,0:02:48.90,Default,,0000,0000,0000,,I know there are gonna be some other talks Dialogue: 0,0:02:48.90,0:02:51.73,Default,,0000,0000,0000,,about APIs here later, and I realized that\NI Dialogue: 0,0:02:51.73,0:02:54.87,Default,,0000,0000,0000,,had, I had two kind of competing things that Dialogue: 0,0:02:54.87,0:02:57.48,Default,,0000,0000,0000,,could come together. The first was, I had,\NI Dialogue: 0,0:02:57.48,0:03:00.32,Default,,0000,0000,0000,,had logic in our application that I needed\Nto Dialogue: 0,0:03:00.32,0:03:02.34,Default,,0000,0000,0000,,share in our API. How was I going to Dialogue: 0,0:03:02.34,0:03:03.78,Default,,0000,0000,0000,,do that? Dialogue: 0,0:03:03.78,0:03:07.49,Default,,0000,0000,0000,,And all of our code was sprinkled through\Nvarious Dialogue: 0,0:03:07.49,0:03:10.56,Default,,0000,0000,0000,,bits of our controller and model logic. Secondly,\NI Dialogue: 0,0:03:10.56,0:03:13.43,Default,,0000,0000,0000,,wanted a mechanism to, to have a strategy\Nfor Dialogue: 0,0:03:13.43,0:03:17.80,Default,,0000,0000,0000,,eliminating the technical debt, and what I\Nturned to Dialogue: 0,0:03:17.80,0:03:21.51,Default,,0000,0000,0000,,was domain-driven design hexagonal architectures,\Nand I want to Dialogue: 0,0:03:21.51,0:03:24.07,Default,,0000,0000,0000,,share what we've learnt along the way of doing Dialogue: 0,0:03:24.07,0:03:26.07,Default,,0000,0000,0000,,that, and, and where we're going. So I hope Dialogue: 0,0:03:26.07,0:03:29.90,Default,,0000,0000,0000,,you're able to learn something from what we've\Ndone. Dialogue: 0,0:03:29.90,0:03:32.69,Default,,0000,0000,0000,,E.R.: That's great Declan. But what are they\Ngonna Dialogue: 0,0:03:32.69,0:03:33.63,Default,,0000,0000,0000,,get out of it? Dialogue: 0,0:03:33.63,0:03:34.07,Default,,0000,0000,0000,,VIDEO Dialogue: 0,0:03:34.07,0:03:37.37,Default,,0000,0000,0000,,??: Here's a good idea. Have a point! Makes Dialogue: 0,0:03:37.37,0:03:40.77,Default,,0000,0000,0000,,it so much more interesting for the listener! Dialogue: 0,0:03:40.77,0:03:43.66,Default,,0000,0000,0000,,D.W.: Well, that was from Sandy Metz. He said, Dialogue: 0,0:03:43.66,0:03:45.11,Default,,0000,0000,0000,,you know, if you're gonna have a talk, you Dialogue: 0,0:03:45.11,0:03:46.78,Default,,0000,0000,0000,,should really have a point, and I think Steve Dialogue: 0,0:03:46.78,0:03:50.08,Default,,0000,0000,0000,,Martin said it pretty funnily. And I guess,\Nour, Dialogue: 0,0:03:50.08,0:03:52.66,Default,,0000,0000,0000,,our number one point is that, there is complexity Dialogue: 0,0:03:52.66,0:03:55.76,Default,,0000,0000,0000,,in the software that we build. There's complexities\Nin Dialogue: 0,0:03:55.76,0:03:57.40,Default,,0000,0000,0000,,the problems that we're solving. And we need\Nto Dialogue: 0,0:03:57.40,0:04:00.29,Default,,0000,0000,0000,,embrace that complexity and embrace it in\Nsuch a Dialogue: 0,0:04:00.29,0:04:02.35,Default,,0000,0000,0000,,way that we tackle it and deal with it. Dialogue: 0,0:04:02.35,0:04:05.60,Default,,0000,0000,0000,,And deal with it head-on. And by doing that, Dialogue: 0,0:04:05.60,0:04:07.73,Default,,0000,0000,0000,,then we end up having more joy and fun Dialogue: 0,0:04:07.73,0:04:09.60,Default,,0000,0000,0000,,in our work because it's not just about getting Dialogue: 0,0:04:09.60,0:04:11.97,Default,,0000,0000,0000,,this functional piece to work, it's about\Nreally trying Dialogue: 0,0:04:11.97,0:04:14.81,Default,,0000,0000,0000,,to understand our domain and model it and\Nexpress Dialogue: 0,0:04:14.81,0:04:16.43,Default,,0000,0000,0000,,that in our code and make our code as Dialogue: 0,0:04:16.43,0:04:18.64,Default,,0000,0000,0000,,expressive as possible. Dialogue: 0,0:04:18.64,0:04:21.83,Default,,0000,0000,0000,,And the second thing that I really realized\Nwas Dialogue: 0,0:04:21.83,0:04:23.69,Default,,0000,0000,0000,,I knew that our code was a mess, and Dialogue: 0,0:04:23.69,0:04:26.59,Default,,0000,0000,0000,,I knew some point refactorings that we could\Ndo, Dialogue: 0,0:04:26.59,0:04:28.86,Default,,0000,0000,0000,,but I didn't know how to, how to, you Dialogue: 0,0:04:28.86,0:04:30.69,Default,,0000,0000,0000,,know, what did the end look like? If it Dialogue: 0,0:04:30.69,0:04:33.78,Default,,0000,0000,0000,,was refactored significantly, what would it\Nlook like? What Dialogue: 0,0:04:33.78,0:04:36.84,Default,,0000,0000,0000,,would the shape look like? What would the\Nnamespaces Dialogue: 0,0:04:36.84,0:04:39.42,Default,,0000,0000,0000,,be? What would the classes be doing, et cetera. Dialogue: 0,0:04:39.42,0:04:43.38,Default,,0000,0000,0000,,And domain-driven design and hexagonal architecture\Nhelped me envision Dialogue: 0,0:04:43.38,0:04:45.10,Default,,0000,0000,0000,,and share with my team what it might look Dialogue: 0,0:04:45.10,0:04:45.97,Default,,0000,0000,0000,,like. Dialogue: 0,0:04:45.97,0:04:49.87,Default,,0000,0000,0000,,The third thing that, that, that we would\Nlike Dialogue: 0,0:04:49.87,0:04:52.29,Default,,0000,0000,0000,,you to take away from this talk is that Dialogue: 0,0:04:52.29,0:04:55.18,Default,,0000,0000,0000,,there's a lot more to just being a Rails Dialogue: 0,0:04:55.18,0:04:58.70,Default,,0000,0000,0000,,developer, the, the ideas and patterns, if\Nyou will, Dialogue: 0,0:04:58.70,0:05:01.34,Default,,0000,0000,0000,,that we, that we're talking about are, some\Nof Dialogue: 0,0:05:01.34,0:05:03.34,Default,,0000,0000,0000,,them have been written by some of those people Dialogue: 0,0:05:03.34,0:05:08.12,Default,,0000,0000,0000,,that DHH had in his slide, including James\NCoplain. Dialogue: 0,0:05:08.12,0:05:09.95,Default,,0000,0000,0000,,But a lot of those patterns have been around Dialogue: 0,0:05:09.95,0:05:12.25,Default,,0000,0000,0000,,for a long time. SO those patterns and those Dialogue: 0,0:05:12.25,0:05:15.82,Default,,0000,0000,0000,,ideas and those practices will serve you well\Nbeyond Dialogue: 0,0:05:15.82,0:05:18.65,Default,,0000,0000,0000,,Rails. They would work in a node application.\NThey Dialogue: 0,0:05:18.65,0:05:20.68,Default,,0000,0000,0000,,could work in a desktop application. They\Ncan work Dialogue: 0,0:05:20.68,0:05:23.26,Default,,0000,0000,0000,,in a wide variety of areas. So by getting Dialogue: 0,0:05:23.26,0:05:26.40,Default,,0000,0000,0000,,some familiarity with these concepts, you're\Nable to transfer Dialogue: 0,0:05:26.40,0:05:30.09,Default,,0000,0000,0000,,those skills to things beyond Rails. Dialogue: 0,0:05:30.09,0:05:33.18,Default,,0000,0000,0000,,And so I want to ask Eric just to Dialogue: 0,0:05:33.18,0:05:34.81,Default,,0000,0000,0000,,walk us through kind of some of the, some Dialogue: 0,0:05:34.81,0:05:36.72,Default,,0000,0000,0000,,of the pain that we had with our initial Dialogue: 0,0:05:36.72,0:05:39.24,Default,,0000,0000,0000,,Rails development and see if it resonates\Nwith you. Dialogue: 0,0:05:39.24,0:05:43.58,Default,,0000,0000,0000,,E.R.: All right. So everyone knows what this\Nis. Dialogue: 0,0:05:43.58,0:05:47.55,Default,,0000,0000,0000,,It's a Rails folder structure. And it's really\Ngreat Dialogue: 0,0:05:47.55,0:05:49.47,Default,,0000,0000,0000,,when you get started with Rails. You have\Nthese Dialogue: 0,0:05:49.47,0:05:53.46,Default,,0000,0000,0000,,folders. OK. I, I logically, my things fall\Ninto Dialogue: 0,0:05:53.46,0:05:56.30,Default,,0000,0000,0000,,these areas. Controllers, models, and views\Nare really what Dialogue: 0,0:05:56.30,0:05:59.24,Default,,0000,0000,0000,,we're focusing on right now. Dialogue: 0,0:05:59.24,0:06:01.11,Default,,0000,0000,0000,,But if the responsibility of your code doesn't\Nstart Dialogue: 0,0:06:01.11,0:06:05.11,Default,,0000,0000,0000,,with M, V or C, what do you do Dialogue: 0,0:06:05.11,0:06:07.61,Default,,0000,0000,0000,,then? And we, and we find it kind of Dialogue: 0,0:06:07.61,0:06:10.05,Default,,0000,0000,0000,,goes like this. You have, you have these areas Dialogue: 0,0:06:10.05,0:06:12.97,Default,,0000,0000,0000,,of responsibility and you have something that\Ndoesn't really Dialogue: 0,0:06:12.97,0:06:14.56,Default,,0000,0000,0000,,fit, and you don't know where it goes, so Dialogue: 0,0:06:14.56,0:06:16.21,Default,,0000,0000,0000,,you just put it on somewhere and things get Dialogue: 0,0:06:16.21,0:06:18.17,Default,,0000,0000,0000,,a little bigger. Dialogue: 0,0:06:18.17,0:06:20.06,Default,,0000,0000,0000,,And continuing on, you keep doing this, things\Nget Dialogue: 0,0:06:20.06,0:06:23.52,Default,,0000,0000,0000,,bigger, and finally, like, the line between\Nall of Dialogue: 0,0:06:23.52,0:06:26.15,Default,,0000,0000,0000,,these things is, is blurred. You don't know\Nwhat's Dialogue: 0,0:06:26.15,0:06:29.50,Default,,0000,0000,0000,,what. It's hard to extract reusable parts\Nfrom all Dialogue: 0,0:06:29.50,0:06:31.81,Default,,0000,0000,0000,,of this, because the, the responsibilities\Nare split across Dialogue: 0,0:06:31.81,0:06:32.39,Default,,0000,0000,0000,,all these things. Dialogue: 0,0:06:32.39,0:06:34.31,Default,,0000,0000,0000,,And you kind of end up with methods like Dialogue: 0,0:06:34.31,0:06:37.72,Default,,0000,0000,0000,,this. This is one method. It starts on the Dialogue: 0,0:06:37.72,0:06:40.36,Default,,0000,0000,0000,,left and ends on the right. It's about ninety Dialogue: 0,0:06:40.36,0:06:43.37,Default,,0000,0000,0000,,lines. Dialogue: 0,0:06:43.37,0:06:46.20,Default,,0000,0000,0000,,It's not from PrintChomp. It's from another,\Nanother project Dialogue: 0,0:06:46.20,0:06:49.19,Default,,0000,0000,0000,,that I've worked on. And without setting,\Nit doesn't Dialogue: 0,0:06:49.19,0:06:51.21,Default,,0000,0000,0000,,really matter what it does. The point is it's Dialogue: 0,0:06:51.21,0:06:55.33,Default,,0000,0000,0000,,ugly and you know, it is actually about setting Dialogue: 0,0:06:55.33,0:06:59.75,Default,,0000,0000,0000,,prices on properties and the date ranges are\Navailable. Dialogue: 0,0:06:59.75,0:07:03.06,Default,,0000,0000,0000,,So I have a question. We need to add Dialogue: 0,0:07:03.06,0:07:05.14,Default,,0000,0000,0000,,sales tax to the prices. Dialogue: 0,0:07:05.14,0:07:09.97,Default,,0000,0000,0000,,Anybody care to take on that refactoring? Dialogue: 0,0:07:09.97,0:07:12.41,Default,,0000,0000,0000,,It's pretty horrible. But nobody, nobody sits\Ndown and Dialogue: 0,0:07:12.41,0:07:14.27,Default,,0000,0000,0000,,says, I'm gonna write a ninety line method\Ntoday Dialogue: 0,0:07:14.27,0:07:19.59,Default,,0000,0000,0000,,that does property prices with date ranges.\NThe initial Dialogue: 0,0:07:19.59,0:07:23.33,Default,,0000,0000,0000,,spec was probably something a lot simpler.\NAnd because Dialogue: 0,0:07:23.33,0:07:25.64,Default,,0000,0000,0000,,it's in that spot now, the next person who Dialogue: 0,0:07:25.64,0:07:27.17,Default,,0000,0000,0000,,comes, comes and looks and that method and\Ngoes, Dialogue: 0,0:07:27.17,0:07:28.50,Default,,0000,0000,0000,,oh, well OK, well if I just type this Dialogue: 0,0:07:28.50,0:07:31.71,Default,,0000,0000,0000,,little bit more it'll, it'll do that now. Dialogue: 0,0:07:31.71,0:07:33.87,Default,,0000,0000,0000,,And this was a little bit of a train Dialogue: 0,0:07:33.87,0:07:36.57,Default,,0000,0000,0000,,wreck. At some point you probably, the people\Nworking Dialogue: 0,0:07:36.57,0:07:39.30,Default,,0000,0000,0000,,on this, including myself, probably should\Nhave realized, you Dialogue: 0,0:07:39.30,0:07:41.33,Default,,0000,0000,0000,,know, forty-five lines might have been the\Ntime to Dialogue: 0,0:07:41.33,0:07:45.79,Default,,0000,0000,0000,,split it up. Maybe twenty. Maybe less. Dialogue: 0,0:07:45.79,0:07:47.89,Default,,0000,0000,0000,,But this is, nonetheless, what we ended up\Nwith. Dialogue: 0,0:07:47.89,0:07:51.12,Default,,0000,0000,0000,,Or, you end up with Rube Goldberg machines\Nfor Dialogue: 0,0:07:51.12,0:07:53.26,Default,,0000,0000,0000,,sharpening pencils. Dialogue: 0,0:07:53.26,0:07:56.21,Default,,0000,0000,0000,,So there's a lot of well-known patterns that\Ncan Dialogue: 0,0:07:56.21,0:07:58.48,Default,,0000,0000,0000,,help you out with this. Has anyone read this Dialogue: 0,0:07:58.48,0:08:03.21,Default,,0000,0000,0000,,blog post? Yeah. Anybody use any of the patterns Dialogue: 0,0:08:03.21,0:08:04.15,Default,,0000,0000,0000,,in them? Dialogue: 0,0:08:04.15,0:08:07.43,Default,,0000,0000,0000,,They're pretty great, right. We use a lot\Nof Dialogue: 0,0:08:07.43,0:08:09.45,Default,,0000,0000,0000,,them, and I'm, we're gonna tell you about\Nsome Dialogue: 0,0:08:09.45,0:08:13.23,Default,,0000,0000,0000,,of them here. But the one thing you've, so Dialogue: 0,0:08:13.23,0:08:16.30,Default,,0000,0000,0000,,you've extracted all of these things into\Nsmall responsibilities. Dialogue: 0,0:08:16.30,0:08:18.23,Default,,0000,0000,0000,,Your models, your controllers and your views.\NThey're all Dialogue: 0,0:08:18.23,0:08:19.25,Default,,0000,0000,0000,,small again. Dialogue: 0,0:08:19.25,0:08:22.31,Default,,0000,0000,0000,,But, OK, so what? I have a bunch of Dialogue: 0,0:08:22.31,0:08:24.89,Default,,0000,0000,0000,,little objects that all go, they all know\Ntoo Dialogue: 0,0:08:24.89,0:08:27.78,Default,,0000,0000,0000,,much about each other. They don't fit in any Dialogue: 0,0:08:27.78,0:08:31.72,Default,,0000,0000,0000,,logical structure. They don't, how, how does\Nthis all Dialogue: 0,0:08:31.72,0:08:35.02,Default,,0000,0000,0000,,fit together? You've made, like, an awesome\Nfirst step, Dialogue: 0,0:08:35.02,0:08:36.94,Default,,0000,0000,0000,,in that you have small little pieces that\Nyou Dialogue: 0,0:08:36.94,0:08:40.25,Default,,0000,0000,0000,,can use. But where do you go from there? Dialogue: 0,0:08:40.25,0:08:44.36,Default,,0000,0000,0000,,And we think that looks kind of like this. Dialogue: 0,0:08:44.36,0:08:49.50,Default,,0000,0000,0000,,We think that your domain concepts, services,\Nentities, should Dialogue: 0,0:08:49.50,0:08:53.17,Default,,0000,0000,0000,,be in the middle, and everything else is outside. Dialogue: 0,0:08:53.17,0:08:56.67,Default,,0000,0000,0000,,Your database is an extra concern, your views\Nare Dialogue: 0,0:08:56.67,0:08:58.89,Default,,0000,0000,0000,,an extra concern. The web, and you know, when Dialogue: 0,0:08:58.89,0:09:01.50,Default,,0000,0000,0000,,you're designing the API, as Declan talked\Nabout a Dialogue: 0,0:09:01.50,0:09:03.31,Default,,0000,0000,0000,,little bit, it's an extra concern. So you\Ncan Dialogue: 0,0:09:03.31,0:09:05.55,Default,,0000,0000,0000,,really focus in on the middle of what your Dialogue: 0,0:09:05.55,0:09:06.55,Default,,0000,0000,0000,,application actually does. Dialogue: 0,0:09:06.55,0:09:09.34,Default,,0000,0000,0000,,I'm gonna let Declan talk a little bit more Dialogue: 0,0:09:09.34,0:09:09.96,Default,,0000,0000,0000,,about that Dialogue: 0,0:09:09.96,0:09:13.84,Default,,0000,0000,0000,,D.W.: Has anyone here heard of domain-driven\Ndesign? Oh, Dialogue: 0,0:09:13.84,0:09:16.01,Default,,0000,0000,0000,,quite a few people. Awesome. How many people\Nhave Dialogue: 0,0:09:16.01,0:09:19.89,Default,,0000,0000,0000,,actually, you know, intentionally used it\Nand, and have Dialogue: 0,0:09:19.89,0:09:22.53,Default,,0000,0000,0000,,worked with it? So, a, a number. SO cool. Dialogue: 0,0:09:22.53,0:09:25.68,Default,,0000,0000,0000,,And it can be quite, it can be quite, Dialogue: 0,0:09:25.68,0:09:29.91,Default,,0000,0000,0000,,it can be quite daunting. And this book by Dialogue: 0,0:09:29.91,0:09:31.85,Default,,0000,0000,0000,,Eric Evans is kind of what kicked it off. Dialogue: 0,0:09:31.85,0:09:34.10,Default,,0000,0000,0000,,And this book was I think written in 2005, Dialogue: 0,0:09:34.10,0:09:36.50,Default,,0000,0000,0000,,and it is a really, really great book, but Dialogue: 0,0:09:36.50,0:09:39.27,Default,,0000,0000,0000,,it is actually quite difficult to read. But\Nit's, Dialogue: 0,0:09:39.27,0:09:41.32,Default,,0000,0000,0000,,I think it might be the only technical book Dialogue: 0,0:09:41.32,0:09:43.04,Default,,0000,0000,0000,,I've read twice. Dialogue: 0,0:09:43.04,0:09:44.45,Default,,0000,0000,0000,,And that's partly cause it was really good\Nand Dialogue: 0,0:09:44.45,0:09:47.60,Default,,0000,0000,0000,,partly cause it was rather difficult to get\Nthrough Dialogue: 0,0:09:47.60,0:09:49.26,Default,,0000,0000,0000,,some of it. Did anyone else read this book Dialogue: 0,0:09:49.26,0:09:51.71,Default,,0000,0000,0000,,and have a similar experience? like, it's\Nreally great Dialogue: 0,0:09:51.71,0:09:53.25,Default,,0000,0000,0000,,stuff and you kind of read and it and Dialogue: 0,0:09:53.25,0:09:55.10,Default,,0000,0000,0000,,you go, wow, what does that mean to me? Dialogue: 0,0:09:55.10,0:09:55.48,Default,,0000,0000,0000,,Right? Dialogue: 0,0:09:55.48,0:09:57.92,Default,,0000,0000,0000,,And we, at the end, at the end, we'll Dialogue: 0,0:09:57.92,0:10:00.05,Default,,0000,0000,0000,,be posting our deck, and we'll have some references Dialogue: 0,0:10:00.05,0:10:02.23,Default,,0000,0000,0000,,to other material that, that I've actually\Nfound to Dialogue: 0,0:10:02.23,0:10:05.17,Default,,0000,0000,0000,,be a bit more addressable or a little more Dialogue: 0,0:10:05.17,0:10:07.35,Default,,0000,0000,0000,,consumable. Dialogue: 0,0:10:07.35,0:10:10.55,Default,,0000,0000,0000,,But what Eric Evans talked about was really\Ntackling Dialogue: 0,0:10:10.55,0:10:13.49,Default,,0000,0000,0000,,complexity, and he talks about the, you know,\Nthe Dialogue: 0,0:10:13.49,0:10:18.34,Default,,0000,0000,0000,,critical complexity is really understanding\Nthe domain. What are Dialogue: 0,0:10:18.34,0:10:22.32,Default,,0000,0000,0000,,the business rules that take place inside\Nour systems? Dialogue: 0,0:10:22.32,0:10:23.68,Default,,0000,0000,0000,,If we're gonna add sales tax, what are the Dialogue: 0,0:10:23.68,0:10:25.99,Default,,0000,0000,0000,,business rules for that sales tax? Dialogue: 0,0:10:25.99,0:10:27.90,Default,,0000,0000,0000,,What are the, what are the rules around who Dialogue: 0,0:10:27.90,0:10:30.74,Default,,0000,0000,0000,,can buy what? And by putting those insides\Nand Dialogue: 0,0:10:30.74,0:10:33.54,Default,,0000,0000,0000,,thinking of them as the domain of our system, Dialogue: 0,0:10:33.54,0:10:36.34,Default,,0000,0000,0000,,then we're able to have our outside layers\Njust Dialogue: 0,0:10:36.34,0:10:42.65,Default,,0000,0000,0000,,be, if you will, relatively thin facades,\Nwhich allows Dialogue: 0,0:10:42.65,0:10:45.78,Default,,0000,0000,0000,,us to reuse that logic across APIs, across\Nother Dialogue: 0,0:10:45.78,0:10:48.53,Default,,0000,0000,0000,,applications. We don't have to duplicate all\Nof those Dialogue: 0,0:10:48.53,0:10:50.51,Default,,0000,0000,0000,,business rules. Dialogue: 0,0:10:50.51,0:10:52.62,Default,,0000,0000,0000,,And the way that he proposes to do that Dialogue: 0,0:10:52.62,0:10:56.48,Default,,0000,0000,0000,,is through ubiquitous language. And this is\Na picture Dialogue: 0,0:10:56.48,0:10:58.92,Default,,0000,0000,0000,,of the tower of Babel and if anybody knows Dialogue: 0,0:10:58.92,0:11:01.82,Default,,0000,0000,0000,,the story, it's where everyone in the world\Nwas Dialogue: 0,0:11:01.82,0:11:04.85,Default,,0000,0000,0000,,speaking a different language and, I once\Nworked on Dialogue: 0,0:11:04.85,0:11:09.24,Default,,0000,0000,0000,,a project that was a financial transaction\Nprocessing system, Dialogue: 0,0:11:09.24,0:11:12.14,Default,,0000,0000,0000,,and when I inherited it, the guy who was Dialogue: 0,0:11:12.14,0:11:15.58,Default,,0000,0000,0000,,proceeded me had this, was a model train aficionado, Dialogue: 0,0:11:15.58,0:11:18.56,Default,,0000,0000,0000,,so he had the idea of model trains. So Dialogue: 0,0:11:18.56,0:11:22.20,Default,,0000,0000,0000,,every transaction was like a car, and the\Npayment Dialogue: 0,0:11:22.20,0:11:25.69,Default,,0000,0000,0000,,engines were, were train tracks. And he had\Nall Dialogue: 0,0:11:25.69,0:11:28.83,Default,,0000,0000,0000,,of these metaphors around transaction processing\Nand trains, and Dialogue: 0,0:11:28.83,0:11:30.37,Default,,0000,0000,0000,,was written in Java. Dialogue: 0,0:11:30.37,0:11:31.91,Default,,0000,0000,0000,,So when I was asked to add a new Dialogue: 0,0:11:31.91,0:11:33.97,Default,,0000,0000,0000,,feature, fix a bug, I had to understand the Dialogue: 0,0:11:33.97,0:11:35.88,Default,,0000,0000,0000,,business domain, and then I had to kind of Dialogue: 0,0:11:35.88,0:11:39.06,Default,,0000,0000,0000,,understand, how did that translate into train\Nspeak, and Dialogue: 0,0:11:39.06,0:11:40.36,Default,,0000,0000,0000,,then I had to go look at the Java Dialogue: 0,0:11:40.36,0:11:43.37,Default,,0000,0000,0000,,code to figure it all out, right. So the Dialogue: 0,0:11:43.37,0:11:46.24,Default,,0000,0000,0000,,coding was easy. The hard part was really\Ntrying Dialogue: 0,0:11:46.24,0:11:48.35,Default,,0000,0000,0000,,to understand what was being asked and how\Ndid Dialogue: 0,0:11:48.35,0:11:50.59,Default,,0000,0000,0000,,the code express that, right? Dialogue: 0,0:11:50.59,0:11:52.15,Default,,0000,0000,0000,,And that's what Eric Evans is talking about\Nwith Dialogue: 0,0:11:52.15,0:11:55.21,Default,,0000,0000,0000,,ubiquitous language. We want to have the language\Nthat Dialogue: 0,0:11:55.21,0:11:58.67,Default,,0000,0000,0000,,we speak with domain experts should be readable\Nin Dialogue: 0,0:11:58.67,0:12:01.46,Default,,0000,0000,0000,,the code. If I'm order, if I'm a customer Dialogue: 0,0:12:01.46,0:12:04.30,Default,,0000,0000,0000,,and I can purchase a product, there should\Nbe Dialogue: 0,0:12:04.30,0:12:06.26,Default,,0000,0000,0000,,a class called customer. There should be a\Nclass Dialogue: 0,0:12:06.26,0:12:08.32,Default,,0000,0000,0000,,called product. And there should be a verb\Nin Dialogue: 0,0:12:08.32,0:12:11.12,Default,,0000,0000,0000,,there that's somewhere that says purchase,\Net cetera. Dialogue: 0,0:12:11.12,0:12:14.02,Default,,0000,0000,0000,,So that there's minimal translation between\Nthe domain experts' Dialogue: 0,0:12:14.02,0:12:16.77,Default,,0000,0000,0000,,language and the language that my code is\Nwritten Dialogue: 0,0:12:16.77,0:12:18.96,Default,,0000,0000,0000,,in. Ruby gives us a great opportunity to do Dialogue: 0,0:12:18.96,0:12:22.37,Default,,0000,0000,0000,,that, but this is much more difficult in,\Nin Dialogue: 0,0:12:22.37,0:12:26.68,Default,,0000,0000,0000,,other more statically typed languages. Dialogue: 0,0:12:26.68,0:12:28.19,Default,,0000,0000,0000,,So that's kind of the, the key thing to Dialogue: 0,0:12:28.19,0:12:30.100,Default,,0000,0000,0000,,take away from domain driven design is to\Ntry Dialogue: 0,0:12:30.100,0:12:34.23,Default,,0000,0000,0000,,to have your, your concepts expressed in code\Nthat Dialogue: 0,0:12:34.23,0:12:37.23,Default,,0000,0000,0000,,are meaningful in the words people use. Dialogue: 0,0:12:37.23,0:12:38.45,Default,,0000,0000,0000,,If they use the word customer, you should\Nhave Dialogue: 0,0:12:38.45,0:12:40.54,Default,,0000,0000,0000,,a customer class. If they use the word user, Dialogue: 0,0:12:40.54,0:12:44.20,Default,,0000,0000,0000,,you should have a user class, et cetera. Dialogue: 0,0:12:44.20,0:12:46.17,Default,,0000,0000,0000,,But beyond that, it also has some kind of Dialogue: 0,0:12:46.17,0:12:50.34,Default,,0000,0000,0000,,key, I, I dare not say it, patterns? Now, Dialogue: 0,0:12:50.34,0:12:53.93,Default,,0000,0000,0000,,I'm almost nervous now to say it. Dialogue: 0,0:12:53.93,0:13:00.93,Default,,0000,0000,0000,,But let me be clear. This isn't science. It's Dialogue: 0,0:13:01.97,0:13:05.82,Default,,0000,0000,0000,,not, right. Because these patterns were not\Ndreamed up Dialogue: 0,0:13:05.82,0:13:10.52,Default,,0000,0000,0000,,in academia ivory towers. These patterns that\Nwe talk Dialogue: 0,0:13:10.52,0:13:15.17,Default,,0000,0000,0000,,about were empirically derived from people\Nintentionally doing what Dialogue: 0,0:13:15.17,0:13:17.90,Default,,0000,0000,0000,,we do, which is write code every day, intentionally Dialogue: 0,0:13:17.90,0:13:20.28,Default,,0000,0000,0000,,thinking about, how does that, how does those,\Nhow Dialogue: 0,0:13:20.28,0:13:22.12,Default,,0000,0000,0000,,do those things fit together, and what is\Nthe Dialogue: 0,0:13:22.12,0:13:23.92,Default,,0000,0000,0000,,essence of what I'm doing? Dialogue: 0,0:13:23.92,0:13:25.100,Default,,0000,0000,0000,,And can I extract that into words that I Dialogue: 0,0:13:25.100,0:13:28.81,Default,,0000,0000,0000,,can use to communicate with other people?\NThe beauty Dialogue: 0,0:13:28.81,0:13:30.57,Default,,0000,0000,0000,,of patterns is I can talk about a value Dialogue: 0,0:13:30.57,0:13:33.34,Default,,0000,0000,0000,,object, and if you know what a value object Dialogue: 0,0:13:33.34,0:13:35.53,Default,,0000,0000,0000,,is and I know what a value object is, Dialogue: 0,0:13:35.53,0:13:38.12,Default,,0000,0000,0000,,we can have a much richer conversation than,\Noh, Dialogue: 0,0:13:38.12,0:13:40.08,Default,,0000,0000,0000,,I have to have an object whose state is, Dialogue: 0,0:13:40.08,0:13:42.12,Default,,0000,0000,0000,,whose identity is defined by the state of\Nits Dialogue: 0,0:13:42.12,0:13:44.14,Default,,0000,0000,0000,,attributes and then, you know, we can have\Na Dialogue: 0,0:13:44.14,0:13:45.42,Default,,0000,0000,0000,,much richer conversation. Dialogue: 0,0:13:45.42,0:13:48.16,Default,,0000,0000,0000,,E.R.: You might say you ubiquitous language. Dialogue: 0,0:13:48.16,0:13:50.42,Default,,0000,0000,0000,,D.W.: Yeah. So we're gonna touch a little\Nbit Dialogue: 0,0:13:50.42,0:13:53.21,Default,,0000,0000,0000,,on some of these patterns. But, but the idea Dialogue: 0,0:13:53.21,0:13:59.23,Default,,0000,0000,0000,,is that these are not academic ivory tower\Nconcepts. Dialogue: 0,0:13:59.23,0:14:01.42,Default,,0000,0000,0000,,These are empirically driven from people who've\Nworked in Dialogue: 0,0:14:01.42,0:14:03.43,Default,,0000,0000,0000,,the field. And if we're gonna, if we're gonna Dialogue: 0,0:14:03.43,0:14:06.33,Default,,0000,0000,0000,,be successful as an organization, while I\Nfully agree Dialogue: 0,0:14:06.33,0:14:08.02,Default,,0000,0000,0000,,that we need to go out and write code Dialogue: 0,0:14:08.02,0:14:09.92,Default,,0000,0000,0000,,and we need to read code, I totally think Dialogue: 0,0:14:09.92,0:14:12.27,Default,,0000,0000,0000,,that's true, but we also have to have more Dialogue: 0,0:14:12.27,0:14:15.51,Default,,0000,0000,0000,,effective ways of communicating knowledge,\Nso that we're not Dialogue: 0,0:14:15.51,0:14:17.55,Default,,0000,0000,0000,,all learning the same things from each other\Nover Dialogue: 0,0:14:17.55,0:14:19.30,Default,,0000,0000,0000,,and over. WE can learn more easily from each Dialogue: 0,0:14:19.30,0:14:22.70,Default,,0000,0000,0000,,other. And that's what these patterns are. Dialogue: 0,0:14:22.70,0:14:27.10,Default,,0000,0000,0000,,And the next kind of piece that we're gonna Dialogue: 0,0:14:27.10,0:14:29.69,Default,,0000,0000,0000,,talk about is hexagonal architectures. And\Nit's more than Dialogue: 0,0:14:29.69,0:14:33.45,Default,,0000,0000,0000,,just that. I think we've alluded to a little Dialogue: 0,0:14:33.45,0:14:36.24,Default,,0000,0000,0000,,bit. It's really the idea of, you're going\Nto Dialogue: 0,0:14:36.24,0:14:42.40,Default,,0000,0000,0000,,have this core domain in the middle, and in, Dialogue: 0,0:14:42.40,0:14:45.12,Default,,0000,0000,0000,,inside your code, surrounding your outside\Ncore are gonna Dialogue: 0,0:14:45.12,0:14:49.32,Default,,0000,0000,0000,,be some application level code that expresses\Nthe rules Dialogue: 0,0:14:49.32,0:14:51.48,Default,,0000,0000,0000,,of your application. And I would draw it slightly Dialogue: 0,0:14:51.48,0:14:53.95,Default,,0000,0000,0000,,differently, perhaps, but, and then we have\Nadapters on Dialogue: 0,0:14:53.95,0:14:56.91,Default,,0000,0000,0000,,the outside that adapt that code to web calls Dialogue: 0,0:14:56.91,0:15:01.12,Default,,0000,0000,0000,,or database calls or SNTP, or in my case, Dialogue: 0,0:15:01.12,0:15:01.63,Default,,0000,0000,0000,,APIs. Dialogue: 0,0:15:01.63,0:15:03.100,Default,,0000,0000,0000,,And so that's the way that we want you Dialogue: 0,0:15:03.100,0:15:05.64,Default,,0000,0000,0000,,to, that's the way that we are starting to Dialogue: 0,0:15:05.64,0:15:08.13,Default,,0000,0000,0000,,approach the work at PrintChomp is thinking\Nabout it Dialogue: 0,0:15:08.13,0:15:10.55,Default,,0000,0000,0000,,in those constructs. And now we want to jump Dialogue: 0,0:15:10.55,0:15:13.86,Default,,0000,0000,0000,,to some specific patterns and, and show you\Nsome Dialogue: 0,0:15:13.86,0:15:16.35,Default,,0000,0000,0000,,real code that actually, you know, brings\Nthese to Dialogue: 0,0:15:16.35,0:15:19.66,Default,,0000,0000,0000,,life. So Eric, you want to talk about form Dialogue: 0,0:15:19.66,0:15:19.97,Default,,0000,0000,0000,,object? Dialogue: 0,0:15:19.97,0:15:21.77,Default,,0000,0000,0000,,E.R.: Sure. Unfortunately, I can't tell you\Nwhat your Dialogue: 0,0:15:21.77,0:15:24.14,Default,,0000,0000,0000,,domain is or what necessarily goes in the\Nmiddle Dialogue: 0,0:15:24.14,0:15:27.06,Default,,0000,0000,0000,,of that hexagon. But I can give you some Dialogue: 0,0:15:27.06,0:15:29.88,Default,,0000,0000,0000,,ways to keep other things out of that hexagon Dialogue: 0,0:15:29.88,0:15:32.27,Default,,0000,0000,0000,,that you don't need to be concerned with. Dialogue: 0,0:15:32.27,0:15:34.24,Default,,0000,0000,0000,,One thing that I've been doing lately is form Dialogue: 0,0:15:34.24,0:15:37.39,Default,,0000,0000,0000,,object. One of the really cool things, you\Nknow, Dialogue: 0,0:15:37.39,0:15:40.35,Default,,0000,0000,0000,,if you run Rails scaffold, some model name,\Nyou Dialogue: 0,0:15:40.35,0:15:43.07,Default,,0000,0000,0000,,get a form that you submit, creates the record, Dialogue: 0,0:15:43.07,0:15:47.21,Default,,0000,0000,0000,,edits the record. And that's pretty great. Dialogue: 0,0:15:47.21,0:15:49.11,Default,,0000,0000,0000,,But how do you do that when you don't Dialogue: 0,0:15:49.11,0:15:53.22,Default,,0000,0000,0000,,have a direct one-one mapping with an ActiveModel\Nrecord? Dialogue: 0,0:15:53.22,0:15:56.83,Default,,0000,0000,0000,,So instead of instantiating an ActiveModel\Nrecord, I've taken Dialogue: 0,0:15:56.83,0:15:59.96,Default,,0000,0000,0000,,to instantiating, I'm gonna call it a form\Nobject. Dialogue: 0,0:15:59.96,0:16:01.60,Default,,0000,0000,0000,,There's a lot of names for a lot of Dialogue: 0,0:16:01.60,0:16:03.41,Default,,0000,0000,0000,,different things. But this is, this is what\NI've Dialogue: 0,0:16:03.41,0:16:04.55,Default,,0000,0000,0000,,been calling it. Dialogue: 0,0:16:04.55,0:16:08.01,Default,,0000,0000,0000,,So here's the actual thing that I was building. Dialogue: 0,0:16:08.01,0:16:10.05,Default,,0000,0000,0000,,On the left hand side, you see that you Dialogue: 0,0:16:10.05,0:16:11.100,Default,,0000,0000,0000,,select a ticket price. On the right hand side, Dialogue: 0,0:16:11.100,0:16:15.23,Default,,0000,0000,0000,,your name, email address, and your payment\Ndetails. And Dialogue: 0,0:16:15.23,0:16:20.06,Default,,0000,0000,0000,,this is actually two ActiveRecord models in\Nmy database. Dialogue: 0,0:16:20.06,0:16:22.94,Default,,0000,0000,0000,,The, the passengers over there on the right,\Nyou Dialogue: 0,0:16:22.94,0:16:25.46,Default,,0000,0000,0000,,can add a passenger and keep adding it. Dialogue: 0,0:16:25.46,0:16:27.16,Default,,0000,0000,0000,,And if you've ever worked with nested attributes,\Nprobably Dialogue: 0,0:16:27.16,0:16:31.14,Default,,0000,0000,0000,,know it's not always that fun. So this is Dialogue: 0,0:16:31.14,0:16:35.39,Default,,0000,0000,0000,,not using nested attributes. It's done like\Nthis. I Dialogue: 0,0:16:35.39,0:16:39.24,Default,,0000,0000,0000,,have a class TicketForm that includes ActiveModel::Model,\Nwhich is Dialogue: 0,0:16:39.24,0:16:41.91,Default,,0000,0000,0000,,how I get nice things, like that magic initialize Dialogue: 0,0:16:41.91,0:16:45.70,Default,,0000,0000,0000,,method of validators. Dialogue: 0,0:16:45.70,0:16:47.84,Default,,0000,0000,0000,,And the passengers method, if I don't have\Nany, Dialogue: 0,0:16:47.84,0:16:50.11,Default,,0000,0000,0000,,returns me a passenger new. That's how it\Nputs Dialogue: 0,0:16:50.11,0:16:53.17,Default,,0000,0000,0000,,the name and email address for that first\Npassenger. Dialogue: 0,0:16:53.17,0:16:54.76,Default,,0000,0000,0000,,And then tickets, I get out of this by Dialogue: 0,0:16:54.76,0:16:59.38,Default,,0000,0000,0000,,taking my passengers and mapping them into\Nnew objects. Dialogue: 0,0:16:59.38,0:17:01.40,Default,,0000,0000,0000,,In the controller, it looks a little bit like Dialogue: 0,0:17:01.40,0:17:04.82,Default,,0000,0000,0000,,this. So you just pass your params off into Dialogue: 0,0:17:04.82,0:17:06.75,Default,,0000,0000,0000,,that. You get it back out and you have Dialogue: 0,0:17:06.75,0:17:10.89,Default,,0000,0000,0000,,tickets. So instead of if ticket dot save,\NI Dialogue: 0,0:17:10.89,0:17:16.10,Default,,0000,0000,0000,,do if ticket_form valid and ticketCharger\Ncharges successfully, then Dialogue: 0,0:17:16.10,0:17:18.39,Default,,0000,0000,0000,,we've had success. And ticketCharge takes\Ncare of charging Dialogue: 0,0:17:18.39,0:17:20.71,Default,,0000,0000,0000,,my tickets and knowing that, there was only,\Ncause Dialogue: 0,0:17:20.71,0:17:22.82,Default,,0000,0000,0000,,there's only one charge for all the tickets,\Nright. Dialogue: 0,0:17:22.82,0:17:24.93,Default,,0000,0000,0000,,You're paying all at once. No point to split Dialogue: 0,0:17:24.93,0:17:26.45,Default,,0000,0000,0000,,that up. Dialogue: 0,0:17:26.45,0:17:28.70,Default,,0000,0000,0000,,So that's a really useful thing that I've\Nfound Dialogue: 0,0:17:28.70,0:17:31.79,Default,,0000,0000,0000,,to, to help when my mappings aren't just totally, Dialogue: 0,0:17:31.79,0:17:33.25,Default,,0000,0000,0000,,I don't want to just take a record of Dialogue: 0,0:17:33.25,0:17:35.99,Default,,0000,0000,0000,,the database, put it in, or update it. Dialogue: 0,0:17:35.99,0:17:37.36,Default,,0000,0000,0000,,And now Declan's gonna tell you a little bit Dialogue: 0,0:17:37.36,0:17:38.34,Default,,0000,0000,0000,,about request objects. Dialogue: 0,0:17:38.34,0:17:40.30,Default,,0000,0000,0000,,D.W.: Yeah. In this case, has anyone used\Na Dialogue: 0,0:17:40.30,0:17:42.45,Default,,0000,0000,0000,,form object or something like that? So quite\Na Dialogue: 0,0:17:42.45,0:17:43.65,Default,,0000,0000,0000,,few people. Cool. Dialogue: 0,0:17:43.65,0:17:46.50,Default,,0000,0000,0000,,Has, has anyone done, used something called\Na request Dialogue: 0,0:17:46.50,0:17:50.76,Default,,0000,0000,0000,,object? Sort of? I was hoping that I invented Dialogue: 0,0:17:50.76,0:17:53.49,Default,,0000,0000,0000,,this. So maybe I haven't. I don't know. OK. Dialogue: 0,0:17:53.49,0:17:56.32,Default,,0000,0000,0000,,But, request object is now in, you know, think Dialogue: 0,0:17:56.32,0:17:58.32,Default,,0000,0000,0000,,of an API as, we're trying to have a Dialogue: 0,0:17:58.32,0:18:02.73,Default,,0000,0000,0000,,similar behavior to the form object, except\Nwe're trying Dialogue: 0,0:18:02.73,0:18:05.17,Default,,0000,0000,0000,,to take, remember, we're trying to take complexity\Nout Dialogue: 0,0:18:05.17,0:18:06.77,Default,,0000,0000,0000,,of our controllers and out of our models and Dialogue: 0,0:18:06.77,0:18:10.78,Default,,0000,0000,0000,,put them into more, to simplify our systems. Dialogue: 0,0:18:10.78,0:18:13.87,Default,,0000,0000,0000,,So the idea with the request object is that Dialogue: 0,0:18:13.87,0:18:15.24,Default,,0000,0000,0000,,we're gonna pull that code out and put it Dialogue: 0,0:18:15.24,0:18:18.51,Default,,0000,0000,0000,,into the, into the controller. And now the\Nrequest Dialogue: 0,0:18:18.51,0:18:21.21,Default,,0000,0000,0000,,object is going to receive the request. And\Nthe Dialogue: 0,0:18:21.21,0:18:23.15,Default,,0000,0000,0000,,code looks sort of like this, right. Dialogue: 0,0:18:23.15,0:18:26.52,Default,,0000,0000,0000,,There's, I, I've done this slightly differently\Nthan Eric's, Dialogue: 0,0:18:26.52,0:18:28.50,Default,,0000,0000,0000,,Eric's way, in terms of, of, the kind of Dialogue: 0,0:18:28.50,0:18:29.88,Default,,0000,0000,0000,,the core of the class. The core of this Dialogue: 0,0:18:29.88,0:18:33.31,Default,,0000,0000,0000,,class is using a gem called Verdis, which\Ndoes Dialogue: 0,0:18:33.31,0:18:38.80,Default,,0000,0000,0000,,something similar to ActiveModel::Model, except\Nthis allows you basically Dialogue: 0,0:18:38.80,0:18:41.95,Default,,0000,0000,0000,,to have a plain-old Ruby object and, the way, Dialogue: 0,0:18:41.95,0:18:44.72,Default,,0000,0000,0000,,and, the cool part is, that, or, I think Dialogue: 0,0:18:44.72,0:18:47.62,Default,,0000,0000,0000,,it's cool. You can, you can declare attributes,\Nlike Dialogue: 0,0:18:47.62,0:18:49.90,Default,,0000,0000,0000,,this. So I have actually, in my domain layer, Dialogue: 0,0:18:49.90,0:18:51.71,Default,,0000,0000,0000,,I have something called the customer and the\Nbilling Dialogue: 0,0:18:51.71,0:18:54.23,Default,,0000,0000,0000,,and the shipping. And if, if somebody supplies\Nme Dialogue: 0,0:18:54.23,0:18:56.99,Default,,0000,0000,0000,,those three things, then I can complete an\Norder Dialogue: 0,0:18:56.99,0:18:58.79,Default,,0000,0000,0000,,in my system. Dialogue: 0,0:18:58.79,0:19:01.81,Default,,0000,0000,0000,,We've, there are a couple of pieces missing\Nhere, Dialogue: 0,0:19:01.81,0:19:03.98,Default,,0000,0000,0000,,but we wanted to keep it, fit in a Dialogue: 0,0:19:03.98,0:19:07.23,Default,,0000,0000,0000,,slide. But that's basically it. And we have\Nthe Dialogue: 0,0:19:07.23,0:19:10.58,Default,,0000,0000,0000,,validation. And the cool part about this is\Nthat Dialogue: 0,0:19:10.58,0:19:12.44,Default,,0000,0000,0000,,when a request comes in, we just, I just Dialogue: 0,0:19:12.44,0:19:15.43,Default,,0000,0000,0000,,put in a before loop in the controller that Dialogue: 0,0:19:15.43,0:19:18.38,Default,,0000,0000,0000,,has a before filter that just basically instantiates\Nthe Dialogue: 0,0:19:18.38,0:19:23.74,Default,,0000,0000,0000,,request object using some, some reflection\Nto figure out, Dialogue: 0,0:19:23.74,0:19:25.92,Default,,0000,0000,0000,,you know, what is the, what is the controller Dialogue: 0,0:19:25.92,0:19:29.66,Default,,0000,0000,0000,,and what is the action being asked, inferring\Nthe Dialogue: 0,0:19:29.66,0:19:32.87,Default,,0000,0000,0000,,request class, instantiating it, and then\Njust passing it Dialogue: 0,0:19:32.87,0:19:34.90,Default,,0000,0000,0000,,what used to be the params hash. Dialogue: 0,0:19:34.90,0:19:37.14,Default,,0000,0000,0000,,But now it's actually a rich object that I Dialogue: 0,0:19:37.14,0:19:39.74,Default,,0000,0000,0000,,can have validations on, et cetera. So the\Nnet Dialogue: 0,0:19:39.74,0:19:42.49,Default,,0000,0000,0000,,effect of this is that, why would I bother Dialogue: 0,0:19:42.49,0:19:45.52,Default,,0000,0000,0000,,doing this, right? Well, now the controller,\Nyou know, Dialogue: 0,0:19:45.52,0:19:48.10,Default,,0000,0000,0000,,the complexity around validating the request\Nis at the Dialogue: 0,0:19:48.10,0:19:50.49,Default,,0000,0000,0000,,boundary of my system. That doesn't need to\Nleak Dialogue: 0,0:19:50.49,0:19:55.64,Default,,0000,0000,0000,,into the rest of my system. It's almost like, Dialogue: 0,0:19:55.64,0:19:57.15,Default,,0000,0000,0000,,you know, does anybody use, you know at the Dialogue: 0,0:19:57.15,0:19:58.68,Default,,0000,0000,0000,,beginning of your methods, you want to put\Nthe Dialogue: 0,0:19:58.68,0:20:01.10,Default,,0000,0000,0000,,guard clauses to catch the exceptions coming\Nin at Dialogue: 0,0:20:01.10,0:20:02.44,Default,,0000,0000,0000,,the beginning of your methods, so that the\Nrest Dialogue: 0,0:20:02.44,0:20:03.79,Default,,0000,0000,0000,,of your method is simpler? Dialogue: 0,0:20:03.79,0:20:05.69,Default,,0000,0000,0000,,This is doing the same thing, except it's\Ndoing Dialogue: 0,0:20:05.69,0:20:08.05,Default,,0000,0000,0000,,it at, at a higher level abstraction, at the Dialogue: 0,0:20:08.05,0:20:10.11,Default,,0000,0000,0000,,API request level. And I, this has worked\Nout Dialogue: 0,0:20:10.11,0:20:11.95,Default,,0000,0000,0000,,really well for us. So I, I quite like Dialogue: 0,0:20:11.95,0:20:13.82,Default,,0000,0000,0000,,that one. Dialogue: 0,0:20:13.82,0:20:14.75,Default,,0000,0000,0000,,Yeah. Dialogue: 0,0:20:14.75,0:20:18.23,Default,,0000,0000,0000,,E.R.: Great. Service objects are another one\Nthat we've Dialogue: 0,0:20:18.23,0:20:21.41,Default,,0000,0000,0000,,been using. I think DHH actually had one in Dialogue: 0,0:20:21.41,0:20:23.42,Default,,0000,0000,0000,,his presentation. I'll give you a hint, he\Ndidn't Dialogue: 0,0:20:23.42,0:20:27.30,Default,,0000,0000,0000,,like it. Dialogue: 0,0:20:27.30,0:20:29.90,Default,,0000,0000,0000,,He used one, it, it's something instantiated\Nby the Dialogue: 0,0:20:29.90,0:20:32.67,Default,,0000,0000,0000,,controller. We've been looking at controllers\Na little bit Dialogue: 0,0:20:32.67,0:20:35.82,Default,,0000,0000,0000,,as just like, OK, I've received this thing,\Npass Dialogue: 0,0:20:35.82,0:20:37.44,Default,,0000,0000,0000,,it off to somebody else, and then do something Dialogue: 0,0:20:37.44,0:20:40.08,Default,,0000,0000,0000,,with the result. So we want to keep out Dialogue: 0,0:20:40.08,0:20:42.77,Default,,0000,0000,0000,,that procedural code from our controllers,\Nand service objects Dialogue: 0,0:20:42.77,0:20:46.02,Default,,0000,0000,0000,,are one way you can do that using a Dialogue: 0,0:20:46.02,0:20:49.37,Default,,0000,0000,0000,,order service to create orders, we've encapsulated\Nall of Dialogue: 0,0:20:49.37,0:20:53.70,Default,,0000,0000,0000,,the logic about how to create an order in Dialogue: 0,0:20:53.70,0:20:54.27,Default,,0000,0000,0000,,this one area. Dialogue: 0,0:20:54.27,0:20:56.07,Default,,0000,0000,0000,,So if you want to, you can use it Dialogue: 0,0:20:56.07,0:20:57.76,Default,,0000,0000,0000,,from somewhere else, right. You don't have\Nto hit Dialogue: 0,0:20:57.76,0:21:01.76,Default,,0000,0000,0000,,a controller action to create an order. It's\Nreusable Dialogue: 0,0:21:01.76,0:21:06.87,Default,,0000,0000,0000,,and extendable. And it has Declan's magic\Nrepository object Dialogue: 0,0:21:06.87,0:21:10.44,Default,,0000,0000,0000,,in there that we'll get to in a bit. Dialogue: 0,0:21:10.44,0:21:14.27,Default,,0000,0000,0000,,And the controller, again, just, it's very\Nsimple. Do Dialogue: 0,0:21:14.27,0:21:17.90,Default,,0000,0000,0000,,this thing, on success do this, on failure,\Ndo Dialogue: 0,0:21:17.90,0:21:18.31,Default,,0000,0000,0000,,this. Dialogue: 0,0:21:18.31,0:21:20.62,Default,,0000,0000,0000,,So those are a few of the patterns that Dialogue: 0,0:21:20.62,0:21:25.92,Default,,0000,0000,0000,,we've been using to help us with this. So Dialogue: 0,0:21:25.92,0:21:27.90,Default,,0000,0000,0000,,now what? Dialogue: 0,0:21:27.90,0:21:34.55,Default,,0000,0000,0000,,What's, what's the elephant in the room? Anybody? Dialogue: 0,0:21:34.55,0:21:41.55,Default,,0000,0000,0000,,How do you get them into Rails? Yeah. Dialogue: 0,0:21:45.43,0:21:47.98,Default,,0000,0000,0000,,Yeah. That's the one we were thinking of. Dialogue: 0,0:21:47.98,0:21:50.52,Default,,0000,0000,0000,,D.W.: That's, ActiveRecord. Yeah. I mean,\NI mean, the Dialogue: 0,0:21:50.52,0:21:52.96,Default,,0000,0000,0000,,end, and how do you get into Rails. Yes, Dialogue: 0,0:21:52.96,0:21:55.89,Default,,0000,0000,0000,,there are some interesting challenges around\Nthat. But I'm Dialogue: 0,0:21:55.89,0:21:57.90,Default,,0000,0000,0000,,gonna flip you back to the architectural slide\Nand Dialogue: 0,0:21:57.90,0:22:00.75,Default,,0000,0000,0000,,just point out that you see what's happened\Nhere Dialogue: 0,0:22:00.75,0:22:04.19,Default,,0000,0000,0000,,is that we're trying to view the application\Npieces Dialogue: 0,0:22:04.19,0:22:07.19,Default,,0000,0000,0000,,of our solution here being really on the perimeter Dialogue: 0,0:22:07.19,0:22:09.74,Default,,0000,0000,0000,,of our core system. And the core system composed Dialogue: 0,0:22:09.74,0:22:13.98,Default,,0000,0000,0000,,of services that may be servicing API or application Dialogue: 0,0:22:13.98,0:22:16.21,Default,,0000,0000,0000,,requests. Dialogue: 0,0:22:16.21,0:22:19.26,Default,,0000,0000,0000,,We have some services that may be invariant\Nacross Dialogue: 0,0:22:19.26,0:22:21.46,Default,,0000,0000,0000,,any call, and those would be at the very Dialogue: 0,0:22:21.46,0:22:23.62,Default,,0000,0000,0000,,center. And we have things called entities\Nwhich are Dialogue: 0,0:22:23.62,0:22:26.44,Default,,0000,0000,0000,,on the inside. And the key part that's, that Dialogue: 0,0:22:26.44,0:22:28.76,Default,,0000,0000,0000,,we haven't talked about, which actually I'm\Nplanning the Dialogue: 0,0:22:28.76,0:22:32.25,Default,,0000,0000,0000,,most difficult part in this is this repository\Nwhich Dialogue: 0,0:22:32.25,0:22:33.80,Default,,0000,0000,0000,,is the bottom, which is the r in the Dialogue: 0,0:22:33.80,0:22:35.57,Default,,0000,0000,0000,,bottom right hand corner. Dialogue: 0,0:22:35.57,0:22:37.87,Default,,0000,0000,0000,,And it's job is to talk to the ActiveRecord Dialogue: 0,0:22:37.87,0:22:39.73,Default,,0000,0000,0000,,model which is in the green, and create an Dialogue: 0,0:22:39.73,0:22:42.28,Default,,0000,0000,0000,,entity object which is the blue object, and,\Nand Dialogue: 0,0:22:42.28,0:22:45.48,Default,,0000,0000,0000,,how does that actually work? So I'm gonna\Nshow Dialogue: 0,0:22:45.48,0:22:48.50,Default,,0000,0000,0000,,you a bit of code, and this is, this Dialogue: 0,0:22:48.50,0:22:50.86,Default,,0000,0000,0000,,is the first time I've shown my Ruby code Dialogue: 0,0:22:50.86,0:22:52.42,Default,,0000,0000,0000,,in public. So please be kind. Dialogue: 0,0:22:52.42,0:22:55.29,Default,,0000,0000,0000,,And there are probably way better ways to\Ndo Dialogue: 0,0:22:55.29,0:22:58.65,Default,,0000,0000,0000,,this. but this is the repository that I've,\NI've, Dialogue: 0,0:22:58.65,0:22:59.71,Default,,0000,0000,0000,,there are some other methods here, but I just Dialogue: 0,0:22:59.71,0:23:01.98,Default,,0000,0000,0000,,wanted to fit on what happen, you know, show Dialogue: 0,0:23:01.98,0:23:03.81,Default,,0000,0000,0000,,you the simple one. Dialogue: 0,0:23:03.81,0:23:05.69,Default,,0000,0000,0000,,So this is what a save looks like. So Dialogue: 0,0:23:05.69,0:23:08.83,Default,,0000,0000,0000,,the save takes a domain object and it converts Dialogue: 0,0:23:08.83,0:23:11.14,Default,,0000,0000,0000,,it through something called a mapper, which\Nmaps the Dialogue: 0,0:23:11.14,0:23:15.44,Default,,0000,0000,0000,,domain object onto a ActiveRecord object,\Nwhich is called Dialogue: 0,0:23:15.44,0:23:18.61,Default,,0000,0000,0000,,a record here. Then I, then it calls record Dialogue: 0,0:23:18.61,0:23:22.40,Default,,0000,0000,0000,,dot save, assigns the id and returns the response. Dialogue: 0,0:23:22.40,0:23:25.06,Default,,0000,0000,0000,,So that's pretty straightforward. All that's\Nreally happened is, Dialogue: 0,0:23:25.06,0:23:26.39,Default,,0000,0000,0000,,and I really tried to do this and so Dialogue: 0,0:23:26.39,0:23:28.29,Default,,0000,0000,0000,,far I've been able to, I don't want to Dialogue: 0,0:23:28.29,0:23:31.01,Default,,0000,0000,0000,,have domain dot save. I want to have repository Dialogue: 0,0:23:31.01,0:23:34.40,Default,,0000,0000,0000,,dot save domain, so that there's no persistence\Nthat's Dialogue: 0,0:23:34.40,0:23:38.25,Default,,0000,0000,0000,,leaking into my domain objects. Persistence,\NI want to Dialogue: 0,0:23:38.25,0:23:40.83,Default,,0000,0000,0000,,be a secondary concern to what that object\Nis Dialogue: 0,0:23:40.83,0:23:41.52,Default,,0000,0000,0000,,really doing. Dialogue: 0,0:23:41.52,0:23:44.14,Default,,0000,0000,0000,,And so far, it's worked, although sometimes\Nit's caused Dialogue: 0,0:23:44.14,0:23:48.04,Default,,0000,0000,0000,,me some difficulty. The method messing down\Nthere is Dialogue: 0,0:23:48.04,0:23:51.71,Default,,0000,0000,0000,,kind of cool. At least I think it's cool. Dialogue: 0,0:23:51.71,0:23:54.50,Default,,0000,0000,0000,,And what it's doing is it's introducing a\Nscope Dialogue: 0,0:23:54.50,0:23:55.97,Default,,0000,0000,0000,,object, which I'll show you in a, well here's Dialogue: 0,0:23:55.97,0:23:57.90,Default,,0000,0000,0000,,the scope object. That's OK. Dialogue: 0,0:23:57.90,0:23:59.65,Default,,0000,0000,0000,,And it creates a scope object, and this was Dialogue: 0,0:23:59.65,0:24:01.63,Default,,0000,0000,0000,,the trickiest code that I had to write, but Dialogue: 0,0:24:01.63,0:24:03.90,Default,,0000,0000,0000,,what it does, what it, the end result of Dialogue: 0,0:24:03.90,0:24:06.97,Default,,0000,0000,0000,,this code is, that allows you to chain call Dialogue: 0,0:24:06.97,0:24:11.09,Default,,0000,0000,0000,,any of your ActiveRecord find methods of your\Nscopes Dialogue: 0,0:24:11.09,0:24:13.40,Default,,0000,0000,0000,,and chain them together. So you can now use, Dialogue: 0,0:24:13.40,0:24:16.03,Default,,0000,0000,0000,,so in other words, with this logic, wherever\Nyou Dialogue: 0,0:24:16.03,0:24:22.01,Default,,0000,0000,0000,,have like ActiveRecord dot, you know, find\Nwhere id Dialogue: 0,0:24:22.01,0:24:24.72,Default,,0000,0000,0000,,greater than 122 is activated and so on, wherever Dialogue: 0,0:24:24.72,0:24:26.31,Default,,0000,0000,0000,,you might have a chain like that, you can Dialogue: 0,0:24:26.31,0:24:28.57,Default,,0000,0000,0000,,still use that chain now because of this scope Dialogue: 0,0:24:28.57,0:24:30.43,Default,,0000,0000,0000,,class with your domain objects. Dialogue: 0,0:24:30.43,0:24:33.74,Default,,0000,0000,0000,,Except, instead of getting back your ActiveRecord\Nobject, you're Dialogue: 0,0:24:33.74,0:24:38.00,Default,,0000,0000,0000,,getting back its domain representation. Does\Nthat make sense? Dialogue: 0,0:24:38.00,0:24:38.60,Default,,0000,0000,0000,,yeah? Dialogue: 0,0:24:38.60,0:24:41.18,Default,,0000,0000,0000,,OK. And then the mapper is what maps them Dialogue: 0,0:24:41.18,0:24:43.95,Default,,0000,0000,0000,,across, right. And some cases, the mapping\Nis like Dialogue: 0,0:24:43.95,0:24:47.44,Default,,0000,0000,0000,,really, really simple. What's the next slide\Nhere? Oh, Dialogue: 0,0:24:47.44,0:24:49.66,Default,,0000,0000,0000,,yeah. Yeah. There it is right there. Dialogue: 0,0:24:49.66,0:24:51.83,Default,,0000,0000,0000,,So the mapper, because of the way vertice\Nworks Dialogue: 0,0:24:51.83,0:24:55.03,Default,,0000,0000,0000,,and the way ActiveRecord works with attributes,\Nyou can Dialogue: 0,0:24:55.03,0:24:57.94,Default,,0000,0000,0000,,almost just instantiate one from the other\Njust passing Dialogue: 0,0:24:57.94,0:25:00.28,Default,,0000,0000,0000,,the attributes back and forth. So it's actually\Nquite Dialogue: 0,0:25:00.28,0:25:04.04,Default,,0000,0000,0000,,easy except when it's not easy, and then what Dialogue: 0,0:25:04.04,0:25:06.74,Default,,0000,0000,0000,,happens, what I'm doing now is just, wherever\NI Dialogue: 0,0:25:06.74,0:25:09.26,Default,,0000,0000,0000,,have something that doesn't fit this model,\NI just Dialogue: 0,0:25:09.26,0:25:12.03,Default,,0000,0000,0000,,subclass this mapper with a custom mapper\Nand override Dialogue: 0,0:25:12.03,0:25:13.65,Default,,0000,0000,0000,,those methods, more or less. Dialogue: 0,0:25:13.65,0:25:17.36,Default,,0000,0000,0000,,And that's the part that I think there, would Dialogue: 0,0:25:17.36,0:25:19.58,Default,,0000,0000,0000,,be more expressive ways to do that mapping\Nand Dialogue: 0,0:25:19.58,0:25:22.22,Default,,0000,0000,0000,,that's what I'm starting to look at now. But Dialogue: 0,0:25:22.22,0:25:25.16,Default,,0000,0000,0000,,so far this has actually worked pretty well. Dialogue: 0,0:25:25.16,0:25:27.83,Default,,0000,0000,0000,,And it's allowed me to completely separate\Nthe way Dialogue: 0,0:25:27.83,0:25:30.54,Default,,0000,0000,0000,,I think about persistence from the way I think Dialogue: 0,0:25:30.54,0:25:32.93,Default,,0000,0000,0000,,about my domain object. SO we before we, before Dialogue: 0,0:25:32.93,0:25:34.91,Default,,0000,0000,0000,,I had this, we had, used to have an Dialogue: 0,0:25:34.91,0:25:37.16,Default,,0000,0000,0000,,order class, and I kid you not, and I'm Dialogue: 0,0:25:37.16,0:25:39.66,Default,,0000,0000,0000,,in, I'm a Rails noob so you can shoot Dialogue: 0,0:25:39.66,0:25:44.65,Default,,0000,0000,0000,,me, but it had forty-eight attributes in the\NActiveRecord::Model, Dialogue: 0,0:25:44.65,0:25:45.54,Default,,0000,0000,0000,,right. Dialogue: 0,0:25:45.54,0:25:48.38,Default,,0000,0000,0000,,That is now represented by about eight classes\Nthat Dialogue: 0,0:25:48.38,0:25:50.96,Default,,0000,0000,0000,,separate out all the different aspects of\Nthe order, Dialogue: 0,0:25:50.96,0:25:56.97,Default,,0000,0000,0000,,like the shipping, the billing, et cetera,\Net cetera. Dialogue: 0,0:25:56.97,0:25:58.92,Default,,0000,0000,0000,,So that, but I think this mapping is, is, Dialogue: 0,0:25:58.92,0:26:01.69,Default,,0000,0000,0000,,is, is one of the more challenging parts.\NAnd Dialogue: 0,0:26:01.69,0:26:05.18,Default,,0000,0000,0000,,then finally, you now I've, then you quickly\Nrun Dialogue: 0,0:26:05.18,0:26:09.89,Default,,0000,0000,0000,,into things like, oh, well what happens if\NI Dialogue: 0,0:26:09.89,0:26:12.24,Default,,0000,0000,0000,,get the record. I get the record, I save Dialogue: 0,0:26:12.24,0:26:13.64,Default,,0000,0000,0000,,it, then I save it again. I have to Dialogue: 0,0:26:13.64,0:26:15.07,Default,,0000,0000,0000,,be able to keep track that I've saved it Dialogue: 0,0:26:15.07,0:26:16.47,Default,,0000,0000,0000,,once already. Dialogue: 0,0:26:16.47,0:26:18.38,Default,,0000,0000,0000,,So that I don't have multiple copies around.\NAnd Dialogue: 0,0:26:18.38,0:26:20.49,Default,,0000,0000,0000,,this is an identity map. In fact, an identity Dialogue: 0,0:26:20.49,0:26:25.25,Default,,0000,0000,0000,,map was built into Rails and I think it Dialogue: 0,0:26:25.25,0:26:26.95,Default,,0000,0000,0000,,might, I don't, I don't work in Rails 4, Dialogue: 0,0:26:26.95,0:26:29.03,Default,,0000,0000,0000,,but I think it might be taken out or, Dialogue: 0,0:26:29.03,0:26:31.48,Default,,0000,0000,0000,,or changed slightly. But actually, on the\Nnext slide Dialogue: 0,0:26:31.48,0:26:33.33,Default,,0000,0000,0000,,I'll show you what the identity map looks\Nlike, Dialogue: 0,0:26:33.33,0:26:34.90,Default,,0000,0000,0000,,and this, actually, I stole from Rails and\Nmade Dialogue: 0,0:26:34.90,0:26:36.51,Default,,0000,0000,0000,,it a bit simpler. Dialogue: 0,0:26:36.51,0:26:37.83,Default,,0000,0000,0000,,But all it's doing is just making sure that Dialogue: 0,0:26:37.83,0:26:42.15,Default,,0000,0000,0000,,there's a unique instance on, on a per-API\Nrequest Dialogue: 0,0:26:42.15,0:26:46.16,Default,,0000,0000,0000,,call for each entity object. So that I, I Dialogue: 0,0:26:46.16,0:26:47.78,Default,,0000,0000,0000,,can, and it actually serves as a really cheap Dialogue: 0,0:26:47.78,0:26:50.89,Default,,0000,0000,0000,,cache, but that's not what it's intent is. Dialogue: 0,0:26:50.89,0:26:54.13,Default,,0000,0000,0000,,So, so that's kind of where, where we're,\Nwhere Dialogue: 0,0:26:54.13,0:26:57.43,Default,,0000,0000,0000,,I'm going now, is most of those service object, Dialogue: 0,0:26:57.43,0:26:59.05,Default,,0000,0000,0000,,form object, request, those all kind of work\Nwell Dialogue: 0,0:26:59.05,0:27:00.98,Default,,0000,0000,0000,,for us, and I'm not looking at what would Dialogue: 0,0:27:00.98,0:27:04.19,Default,,0000,0000,0000,,a repository pattern look like fleshed out.\NAnd that Dialogue: 0,0:27:04.19,0:27:06.08,Default,,0000,0000,0000,,is, by far, the most challenging piece. Dialogue: 0,0:27:06.08,0:27:08.63,Default,,0000,0000,0000,,But I heard a question about where you put Dialogue: 0,0:27:08.63,0:27:11.04,Default,,0000,0000,0000,,things. You can really just put them anywhere.\NYou Dialogue: 0,0:27:11.04,0:27:13.63,Default,,0000,0000,0000,,know. That's the thing, like, Rails just seems\Nto Dialogue: 0,0:27:13.63,0:27:17.82,Default,,0000,0000,0000,,be, there's a part that's, I just felt constrained. Dialogue: 0,0:27:17.82,0:27:20.52,Default,,0000,0000,0000,,Like, Rails didn't give me any guidance on\Nwhere Dialogue: 0,0:27:20.52,0:27:22.30,Default,,0000,0000,0000,,do I put a service socket. Well, you can Dialogue: 0,0:27:22.30,0:27:24.26,Default,,0000,0000,0000,,really put it anywhere you like. You could\Nput Dialogue: 0,0:27:24.26,0:27:26.03,Default,,0000,0000,0000,,it on the auto load path or you can Dialogue: 0,0:27:26.03,0:27:28.52,Default,,0000,0000,0000,,put it where Rails might expect to see it. Dialogue: 0,0:27:28.52,0:27:30.27,Default,,0000,0000,0000,,But it, you can just create a services directory Dialogue: 0,0:27:30.27,0:27:32.07,Default,,0000,0000,0000,,and put your service objects there. Rails\Nwill find Dialogue: 0,0:27:32.07,0:27:34.89,Default,,0000,0000,0000,,it. It's not hard. But Rails doesn't really\Nkind Dialogue: 0,0:27:34.89,0:27:36.71,Default,,0000,0000,0000,,of tell you what to do. So it doesn't Dialogue: 0,0:27:36.71,0:27:39.39,Default,,0000,0000,0000,,make it easy to do these, to think of Dialogue: 0,0:27:39.39,0:27:42.00,Default,,0000,0000,0000,,it, but it actually, it's not hard. Dialogue: 0,0:27:42.00,0:27:45.09,Default,,0000,0000,0000,,And but that's where we're going with that,\Nand Dialogue: 0,0:27:45.09,0:27:46.94,Default,,0000,0000,0000,,we'll, we'll give you a link to it, to, Dialogue: 0,0:27:46.94,0:27:48.97,Default,,0000,0000,0000,,I've started a Git Repo where I plan to Dialogue: 0,0:27:48.97,0:27:51.10,Default,,0000,0000,0000,,share some of these ideas, and if you're interested Dialogue: 0,0:27:51.10,0:27:53.38,Default,,0000,0000,0000,,in sharing ideas with us on that, we'll, we'll Dialogue: 0,0:27:53.38,0:27:58.02,Default,,0000,0000,0000,,be happy to talk to you or, or join Dialogue: 0,0:27:58.02,0:27:59.73,Default,,0000,0000,0000,,us on the, on the Git Repo. Dialogue: 0,0:27:59.73,0:28:04.82,Default,,0000,0000,0000,,E.R.: Right. So what's the point, again? At\Nthe Dialogue: 0,0:28:04.82,0:28:10.58,Default,,0000,0000,0000,,start, we had these three things. Embrace\Ncomplexity. Getting, Dialogue: 0,0:28:10.58,0:28:14.64,Default,,0000,0000,0000,,getting the solution to work is only part\Nof Dialogue: 0,0:28:14.64,0:28:18.09,Default,,0000,0000,0000,,the fun, right? It's, it's your first draft,\Nas Dialogue: 0,0:28:18.09,0:28:20.49,Default,,0000,0000,0000,,DHH said, talking about writing. You get,\Nyou do Dialogue: 0,0:28:20.49,0:28:24.63,Default,,0000,0000,0000,,it over and over. And getting things to work, Dialogue: 0,0:28:24.63,0:28:27.95,Default,,0000,0000,0000,,that ninety-line method I showed earlier,\Nthat worked. But Dialogue: 0,0:28:27.95,0:28:31.05,Default,,0000,0000,0000,,does anyone want to go back and use that Dialogue: 0,0:28:31.05,0:28:33.58,Default,,0000,0000,0000,,again? It's no, it's no fun to revisit, unless Dialogue: 0,0:28:33.58,0:28:36.53,Default,,0000,0000,0000,,you're improving it, which, I did do eventually\Nand, Dialogue: 0,0:28:36.53,0:28:40.99,Default,,0000,0000,0000,,and now it's much nicer to work with. That, Dialogue: 0,0:28:40.99,0:28:44.40,Default,,0000,0000,0000,,that's fun. At least, we think that's fun.\NGetting Dialogue: 0,0:28:44.40,0:28:46.60,Default,,0000,0000,0000,,beyond the problem and getting it to a level Dialogue: 0,0:28:46.60,0:28:49.34,Default,,0000,0000,0000,,where we actually don't mind going into our\Ncode, Dialogue: 0,0:28:49.34,0:28:52.70,Default,,0000,0000,0000,,extending things, and changing things. Dialogue: 0,0:28:52.70,0:28:54.89,Default,,0000,0000,0000,,And we do that by breaking them up into Dialogue: 0,0:28:54.89,0:28:57.55,Default,,0000,0000,0000,,the smaller parts with the patterns that we've\Ntalked Dialogue: 0,0:28:57.55,0:28:57.98,Default,,0000,0000,0000,,about. Dialogue: 0,0:28:57.98,0:29:00.83,Default,,0000,0000,0000,,Knowing where you're going. In Alice in Wonderland,\Nparaphrase, Dialogue: 0,0:29:00.83,0:29:03.32,Default,,0000,0000,0000,,they said if you don't know where you're going, Dialogue: 0,0:29:03.32,0:29:06.55,Default,,0000,0000,0000,,any road will take you there. We think it's Dialogue: 0,0:29:06.55,0:29:08.46,Default,,0000,0000,0000,,important to know where you're going and pick\Na Dialogue: 0,0:29:08.46,0:29:10.12,Default,,0000,0000,0000,,road that you think will take you there. It Dialogue: 0,0:29:10.12,0:29:12.03,Default,,0000,0000,0000,,doesn't have to be our road. These are things Dialogue: 0,0:29:12.03,0:29:14.85,Default,,0000,0000,0000,,that helped us, and, and we think they're\Ngood Dialogue: 0,0:29:14.85,0:29:17.39,Default,,0000,0000,0000,,ideas. But it's not gonna solve every problem\Nfor Dialogue: 0,0:29:17.39,0:29:21.22,Default,,0000,0000,0000,,everyone. These aren't rules. Like Declan\Nsaid, they're not Dialogue: 0,0:29:21.22,0:29:22.83,Default,,0000,0000,0000,,science. You can't just take them and throw\Nthem Dialogue: 0,0:29:22.83,0:29:25.38,Default,,0000,0000,0000,,on and expect that your code will magically\Nget Dialogue: 0,0:29:25.38,0:29:28.32,Default,,0000,0000,0000,,better by going on a diet. Dialogue: 0,0:29:28.32,0:29:31.23,Default,,0000,0000,0000,,And be more than just a Rails developer. Not Dialogue: 0,0:29:31.23,0:29:33.81,Default,,0000,0000,0000,,that it's bad to be a Rails developer, but Dialogue: 0,0:29:33.81,0:29:40.81,Default,,0000,0000,0000,,these things apply across, across languages\Nand stuff. Like, Dialogue: 0,0:29:41.37,0:29:45.37,Default,,0000,0000,0000,,don't just learn Ruby. Learn, learn beyond\Nthat. So Dialogue: 0,0:29:45.37,0:29:49.36,Default,,0000,0000,0000,,as Declan mentioned, we have this GitHUb that\Nwe've Dialogue: 0,0:29:49.36,0:29:51.98,Default,,0000,0000,0000,,set up, and right now it's just a readme. Dialogue: 0,0:29:51.98,0:29:54.54,Default,,0000,0000,0000,,We don't actually have the code in their yet. Dialogue: 0,0:29:54.54,0:29:56.30,Default,,0000,0000,0000,,We'll likely put some of the code we showed Dialogue: 0,0:29:56.30,0:29:58.92,Default,,0000,0000,0000,,today, especially the repository bits. Dialogue: 0,0:29:58.92,0:30:02.18,Default,,0000,0000,0000,,But we'd love to continue the discussion via\Nissues, Dialogue: 0,0:30:02.18,0:30:05.75,Default,,0000,0000,0000,,pull requests, whatever. That would be awesome.\NAnd, and Dialogue: 0,0:30:05.75,0:30:07.00,Default,,0000,0000,0000,,we'd love to talk to you about some of Dialogue: 0,0:30:07.00,0:30:10.53,Default,,0000,0000,0000,,it throughout this week as well. In fact,\NI'm Dialogue: 0,0:30:10.53,0:30:15.13,Default,,0000,0000,0000,,gonna also mentioned, we have reading. You'll\Nbe able Dialogue: 0,0:30:15.13,0:30:18.07,Default,,0000,0000,0000,,to get these slides after, so I'm just gonna Dialogue: 0,0:30:18.07,0:30:19.07,Default,,0000,0000,0000,,gloss over them. Dialogue: 0,0:30:19.07,0:30:21.69,Default,,0000,0000,0000,,These are a couple of the books that we've Dialogue: 0,0:30:21.69,0:30:23.21,Default,,0000,0000,0000,,taken a look at to help us out with Dialogue: 0,0:30:23.21,0:30:23.94,Default,,0000,0000,0000,,these things. Dialogue: 0,0:30:23.94,0:30:26.42,Default,,0000,0000,0000,,D.W.: I think the crowd has spoken and it's Dialogue: 0,0:30:26.42,0:30:28.99,Default,,0000,0000,0000,,time to wrap up. If you want to come Dialogue: 0,0:30:28.99,0:30:31.37,Default,,0000,0000,0000,,up and talk, I'm happy to answer your questions. Dialogue: 0,0:30:31.37,0:30:32.87,Default,,0000,0000,0000,,Thank you.