WEBVTT 00:00:00.000 --> 00:04:43.738 (The talk starts at 4:45) 00:04:46.478 --> 00:04:50.376 Alright you all hear me okay? 00:04:50.785 --> 00:04:56.304 Way in the back up there you hear me alright? Well it's OK, good good good 00:04:56.401 --> 00:05:00.828 Um what is an electron? 00:05:04.013 --> 00:05:07.984 So part of atom, everybody knows that, I think 00:05:08.290 --> 00:05:17.718 It's um.. (Screams from other room) yeah I think so, . I think that's royal ??? 00:05:19.734 --> 00:05:22.415 Electron is part of atom 00:05:22.604 --> 00:05:32.113 It's carries a unit of electronic charge, negative charge, as oppose to a proton which carries a positive charge 00:05:32.230 --> 00:05:42.408 It apparently has mass, though not very much, thousands of electron or something like that. Very very small amount of mass 00:05:42.922 --> 00:05:55.041 And we think of it as a particle, although that's misleading. The electron actually behaves much more like a wave than like a particle 00:05:55.041 --> 00:05:58.778 Why do we think of it as particle? 00:05:58.780 --> 00:06:08.906 And the reason we do that is that when an electron interacts it interacts at a location like a particle would 00:06:09.151 --> 00:06:16.302 But when electron is moving through the space it does not moves the way a particle would 00:06:16.418 --> 00:06:21.498 It moves as a wave and the wave has no location 00:06:21.498 --> 00:06:27.334 You look at an ocean wave, and ocean wave can be huge 00:06:27.334 --> 00:06:33.819 It has no distinct location it has a well defined energy but no distinct location 00:06:33.819 --> 00:06:36.450 This is how an electron moves 00:06:36.450 --> 00:06:42.191 Electrons obey a principle and it's a mistruster principle 00:06:42.191 --> 00:06:45.566 It's called the poly exclusion principle 00:06:45.566 --> 00:06:53.202 Two electrons bound into the same system will not be in the same state 00:06:53.202 --> 00:06:57.328 For whatever reason they cannot be in the same state 00:06:57.328 --> 00:07:00.677 so if there are two electrons in an atom 00:07:00.677 --> 00:07:04.066 those two electrons must be different somehow 00:07:04.066 --> 00:07:07.709 Now they might different in the direction of their spin 00:07:07.709 --> 00:07:10.899 An electron can spin to the left or spin to the right 00:07:10.899 --> 00:07:18.355 Two electrons that have exactly same energy could fit together spinning one left and one right 00:07:18.355 --> 00:07:21.442 There's no way to get a third one in there 00:07:21.450 --> 00:07:28.412 So the next electron must have higher energy and then you can have two more 00:07:28.412 --> 00:07:30.806 One spinning left one spinning right 00:07:30.806 --> 00:07:34.769 But if you wanted to add another that would have to be something different about them 00:07:34.769 --> 00:07:37.917 And you could arrange them differently in space 00:07:37.985 --> 00:07:48.589 So you could have one group of two this way and another group of two this way and another group of two this way and one group of two in a sphere and that adds up the eight by the way. 00:07:49.633 --> 00:07:57.677 Most of our atoms that we know of have this need to have 8 electrons in their shells 00:07:57.690 --> 00:08:07.827 The reason for that is just this nice little geometry. the sphere and then three rows and each one of those can contain two 00:08:07.827 --> 00:08:12.868 Have you ever thought about water? 00:08:12.868 --> 00:08:16.880 I got some here. Fascinating substance 00:08:16.880 --> 00:08:19.898 What's it made of? 00:08:20.484 --> 00:08:25.082 Two hydrogen atoms one oxygen atom that's what makes a water molecule 00:08:25.472 --> 00:08:28.076 And what's it shaped like? 00:08:28.076 --> 00:08:33.482 Mickey mouse! yes, there is big oxygen in the middle and two little hydrogens forming the ears 00:08:33.482 --> 00:08:42.437 The angle there is the result of (??) the shell arrangement. 00:08:42.437 --> 00:08:46.772 What makes the hydrogen and oxygen stick together? 00:08:46.772 --> 00:08:51.162 Think of two atoms, two atoms covered by electrons, two electrons are parallel each other 00:08:51.162 --> 00:08:56.287 What would make two hydrogens and an oxygen stick together? 00:08:56.287 --> 00:09:03.380 And it turns out that if you take these two hydrogens and big oxygen you lay them next to each other 00:09:03.380 --> 00:09:12.156 And you think of the electrons as waves, not particles, then where those waves like to be? 00:09:12.156 --> 00:09:20.400 And those waves would like to be mostly between protons. Protons in hydrogen atom and protons in oxygen atom 00:09:20.400 --> 00:09:25.099 So they will congregate those electron waves will congregate more 00:09:25.099 --> 00:09:30.861 Between two atoms, between three atoms actually, then everywhere else 00:09:30.861 --> 00:09:34.964 They still go everywhere else that just that more likely to be between them 00:09:34.964 --> 00:09:47.718 That means there's little extra negative charge between the atoms and that little extra negative charge to tracks the protons and that's covalent bonds 00:09:47.718 --> 00:09:54.029 Now if you take this Mickey mouse atom and you divide it in half 00:09:54.136 --> 00:09:57.675 You find there's more negative charge above the one and below the one 00:09:57.675 --> 00:10:02.000 Cause all that negative charge likes to sit there between the two hydrogen atoms and oxygen atoms 00:10:02.000 --> 00:10:08.075 So there's more negative charge on one side than the other which means that water molecule is a dipole 00:10:08.075 --> 00:10:10.676 It is negative one side and positive on the other 00:10:10.676 --> 00:10:12.702 This is why water is wet. 00:10:12.702 --> 00:10:20.463 Water sticks to your hand because all the water molecules rotate to stick to the electrically charged surface of your skin 00:10:20.463 --> 00:10:22.614 Even though it is not very electrically charged 00:10:22.614 --> 00:10:33.736 This is why water makes it good solvent because the little water molecules would rotate to attract to the parts of the other molecule that they want want to stick to 00:10:33.772 --> 00:10:37.394 This is why water makes it a good cleanser 00:10:37.394 --> 00:10:42.888 And this is why water will do one of the most wonderful things you can do with water. Who's done this experiment? 00:10:42.888 --> 00:10:51.704 You get a water faucet. You turn it on just so you get a really thin stream of water. Not very fast, just tiny stream of water 00:10:51.704 --> 00:11:02.317 And then you get a balloon and you rub the balloon on your head. And then you hold the balloon close to that stream of water and watch the water bend towards the balloon 00:11:02.317 --> 00:11:06.252 As all the water molecules turn around get it tracked the electric charge 00:11:06.252 --> 00:11:09.585 Of course that's not what we supposed to be talking about 00:11:10.815 --> 00:11:19.975 The name of the talk I'm about to give you is called "Architecture the lost years". It a talk I've been doing for several years. 00:11:20.057 --> 00:11:28.490 It's about the next step after clean code after clean design. 00:11:28.535 --> 00:11:33.876 This is about clean system structure 00:11:33.876 --> 00:11:38.162 And it begins with that 00:11:38.162 --> 00:11:47.069 This is a directory structure of an application I wrote close to ten years ago now 00:11:47.069 --> 00:11:53.089 I was studying Rails. Anybody here Ruby programmer, Ruby on Rails programmer? 00:11:53.089 --> 00:11:56.906 We got a guy over there, waving his hand around. OK. 00:11:57.047 --> 00:12:04.404 I was learning Rails at that time. And I wrote this application 00:12:04.404 --> 00:12:09.735 And it was I followed the book. You get the books out. You follow the book 00:12:09.767 --> 00:12:13.839 Follow all the recommendations of the book and that's what I wound up with 00:12:13.839 --> 00:12:20.077 And I was happy with that. I put the application away and I didn't look at it again for very long time. 00:12:20.140 --> 00:12:27.376 Then about three years ago. My son, at my request, wrote an application. 00:12:27.376 --> 00:12:32.325 And I looked it in and I saw that. 00:12:32.325 --> 00:12:36.174 Same directory structure. 00:12:36.174 --> 00:12:40.573 These are two completely different applications. It had nothing to do with each other. 00:12:40.614 --> 00:12:45.121 But they had same directory structure. And I looked at it and I thought. 00:12:45.121 --> 00:12:52.868 Wait why did these two applications have the same high level structure? 00:12:52.868 --> 00:12:56.646 They are two completely different applications. 00:12:56.646 --> 00:13:02.958 And it occured to me that they had same directory structure because they were both Rails applications. 00:13:02.958 --> 00:13:09.304 And I asked my self, okay but why is that important? 00:13:09.304 --> 00:13:20.673 Why is Rails or any framework so important that it would dominate the high level directory structure of an application? 00:13:20.726 --> 00:13:25.183 And the reason I asset question of myself was because of this. 00:13:25.986 --> 00:13:34.191 The web is a delivery mechanism. The web is an I/O channel. 00:13:34.191 --> 00:13:37.913 The web is not architecturally significant. 00:13:37.980 --> 00:13:42.263 We think of ourselves as writing web applications. 00:13:42.263 --> 00:13:44.786 We are not writing web applications. 00:13:44.786 --> 00:13:51.940 We are writing applications that happened to deliver their content over the I/O channel known as the web. 00:13:51.940 --> 00:13:57.675 And why should that I/O channel dominate us? 00:13:59.785 --> 00:14:06.705 Does anybody remember when the web became important? 1980? 1990? 00:14:06.705 --> 00:14:13.833 Anybody remember what a change that was? How radically different everything was? 00:14:13.833 --> 00:14:19.872 Except that it wasn't. Because we weren't really doing anything new? 00:14:19.872 --> 00:14:26.511 We were just gathering input from an input source. Processing it and spitting it out to an output source. 00:14:26.573 --> 00:14:28.374 That's all the web is. 00:14:28.374 --> 00:14:31.082 Why would web dominate so much? 00:14:31.082 --> 00:14:39.189 So I started to thinking about architecture. And I started to looking at blue prints. 00:14:40.649 --> 00:14:49.599 There's blueprint. and if you didn't have the word library staring at you. it wouldn't take you long to figure out that it was a library. 00:14:49.599 --> 00:14:51.729 Because it's obviously a library. 00:14:51.805 --> 00:14:55.882 You got a bunch of book shelves in there. You got a bunch of reading tables. 00:14:55.882 --> 00:15:05.705 There's little computers sitting on tables. There's an area upfront where you have the desk you can borrow or return books 00:15:05.705 --> 00:15:11.167 It wouldn't take you long to look at that and think "Um.. that must be something like a library." 00:15:11.167 --> 00:15:15.704 Or here's another one. That's a church. It's obviously a church. 00:15:15.704 --> 00:15:20.999 Oh, you might mistake it for a theater. Theater and church do have certain synergy to them. 00:15:20.999 --> 00:15:29.736 But no this is definitely a church. The puse(??), the altar, the classrooms on the outside, the greeting area around the front 00:15:29.736 --> 00:15:31.703 This is clearly a church. 00:15:31.703 --> 00:15:42.315 The architecture of this buildings is not telling you how they built. The architecture of this buildings is telling you what they are for. 00:15:42.315 --> 00:15:49.020 Their intent. Architecture is about intent. 00:15:49.020 --> 00:15:56.016 And the high level structures of those Rails apps were not communicating intent to me. 00:15:56.154 --> 00:16:03.104 They were telling me that they were Rails apps. Something wrong with that. 00:16:03.104 --> 00:16:05.902 And then it occurred to me. 00:16:05.902 --> 00:16:15.087 This is known problem? It's a solved problem. It was recognized and solved by Iva Jacobson in 1992 when he wrote this book. 00:16:15.087 --> 00:16:20.638 Who got this book? Anybody read this one? I got a guy here, anybody else? 00:16:20.677 --> 00:16:23.431 Object-Oriented Software Engineering, if you have. Wonderful Book. 00:16:23.503 --> 00:16:29.821 It's 1992 little bit old, but it doesn't matter. The principles inside still perfectly good. 00:16:29.916 --> 00:16:37.212 Notice the subtitle, the subtitle says "A usecase driven approach" 00:16:37.212 --> 00:16:45.107 Who remembers usecases? Uh.. See? It was very popular in the early 90s. big big deal. 00:16:45.107 --> 00:16:54.199 In fact it was so popular that it was utterly destroyed by all the consultants who invaded the realm and ruined what usecases were supposed to be. 00:16:54.199 --> 00:17:06.426 You may recall if you remember that era that one consultant after another would publish on the Internet their own particular format for usecase. 00:17:06.426 --> 00:17:15.840 And the format became all important. We had PDFs all out there, force you to fill in the blanks of a standard usecase form. 00:17:15.840 --> 00:17:23.318 Anyway the fill in the name of the usecase and the input to the usecase and the precondition and postconditions 00:17:23.318 --> 00:17:29.726 and primary actor and secondary actors and the (???) actor. What the hell is the (???) actor? 00:17:29.726 --> 00:17:38.276 You had to fill in all the stuff and the whole problem of usecases became one of form instead of one of function. 00:17:38.306 --> 00:17:44.214 And right about the peak of the era, the agile movement began. 00:17:44.214 --> 00:17:52.242 And we stop talking about usecases and we started talking about stories and whole usecase thing fell on the floor. Nobody talked about it again. 00:17:52.242 --> 00:17:58.310 And so I brought it up again and I read through the manual again, the book again. 00:17:58.310 --> 00:18:02.105 And I remembered what Jacobson wrote. 00:18:02.168 --> 00:18:11.409 Here is a usecase. Typical of the kind of usecase that Jacobson would have written. 00:18:11.444 --> 00:18:15.646 If you notice that it has very little form. 00:18:15.646 --> 00:18:24.568 Oh a little bit. It's got a name up there created order. Imagine this is a usecase for order processing system. 00:18:24.568 --> 00:18:31.952 And it's got some input data like the customer id and customer contact information and the shipment destination. 00:18:31.952 --> 00:18:37.657 Notice that I'm not supplying any details. I'm not saying what the customer Id is. 00:18:37.657 --> 00:18:40.146 Whether it is a number or string, I don't care. 00:18:40.187 --> 00:18:48.264 I'm not saying what the customer contact info is, I assume it's got a name and a date and a address and few other things. But I don't care. 00:18:48.328 --> 00:18:51.560 I'm not trying to specify the detail here. 00:18:51.599 --> 00:18:55.268 And then you've got the primary course. 00:18:55.268 --> 00:19:04.557 And the primary course is the set of steps that computer will undertake to satisfy the usecase. these're the processing steps. (??) 00:19:04.557 --> 00:19:11.037 And the first one is the order clerk issues the create order command that's actually not something the computer does. 00:19:11.073 --> 00:19:18.511 And the second step is the system validates all the data. Notice I don't say how. Just validate somehow it doesn't matter. 00:19:18.575 --> 00:19:23.542 Third step is system creates the order and determines the order Id. 00:19:23.542 --> 00:19:29.089 I presume that some kind of database operation but I'm not going to say that here. 00:19:29.089 --> 00:19:35.036 And then fourth step is at the system delivers order id to the clerk. Probably a web page but I'm not going to say that. 00:19:35.106 --> 00:19:40.426 In fact, this whole usecase says nothing about the web. 00:19:40.426 --> 00:19:44.456 This usecase would work no matter what the input output channel was. 00:19:44.456 --> 00:19:53.606 I can make this usecase work on a console app, a desktop app, a web app, a service oriented architecture app, I Phone app it doesn't matter. 00:19:53.606 --> 00:19:59.609 Because the usecase is agnostic, it doesn't care about the I/O channel. 00:19:59.609 --> 00:20:09.559 Jacobson said you can take that usecase and turn it into object. 00:20:09.559 --> 00:20:19.878 He called the object a control object. I've changed the name to an interactor to avoid confusion with Model View Controller. 00:20:19.878 --> 00:20:26.239 Maybe I should have change the name to usecase. But I didn't. Interactor is what I've written here. 00:20:26.239 --> 00:20:38.028 The interactor object implements the usecase, it takes as its input, the usecase's input, it delivers as its output, the usecase's output. 00:20:38.028 --> 00:20:45.857 And it implements at least the high level. The rules, the processing steps of the usecase 00:20:45.857 --> 00:20:54.166 Notice there's the caption below there. It says interactors have application specific business rules 00:20:54.166 --> 00:20:56.768 There are two kinds of business rules 00:20:56.768 --> 00:21:06.166 There are the kinds of business rules that are global, they are true no matter what the application is. They are application independent business rules 00:21:06.166 --> 00:21:11.695 And then there are other business rules that are tied to the application you're writing 00:21:11.695 --> 00:21:22.020 So for example, let's say that we've got an order entry application and an order processing application. Two completely different applications 00:21:22.020 --> 00:21:29.693 Both of them might have an order object and that order object might have common business rules 00:21:29.693 --> 00:21:40.739 Regardless of which of the two applications you're inside, but only one of those applications would have insert order usecase 00:21:40.739 --> 00:21:47.910 So usecases are application specific, they're bounded to the particular application they're in 00:21:47.910 --> 00:21:56.696 Business rules that are not application specific are bound to entity objects, some people would call these business objects 00:21:56.727 --> 00:22:01.325 I don't like the term, entity objects that's what Jacobson called them as well 00:22:01.405 --> 00:22:10.785 You put all of the application independent business rules into your entities and the interactor will control the entities. 00:22:10.785 --> 00:22:17.332 Then you have to figure out the way to get the input and the output out of the usecase into another usecase 00:22:17.332 --> 00:22:24.159 We do that in this case with interfaces. I have drawn these as object-oriented interfaces 00:22:24.159 --> 00:22:31.266 And notice that the interactor uses one of the interfaces and derives from the other. 00:22:31.266 --> 00:22:38.233 The one it derives from is the input interface. The one it uses is the output interface 00:22:38.233 --> 00:22:42.174 Notice that the arrows point the same direction, that's important 00:22:42.174 --> 00:22:45.106 We'll come to why that's important in a minute 00:22:45.106 --> 00:22:53.455 So these are the three objects the Jacobson identified as part of his architecture for applications 00:22:53.455 --> 00:22:57.683 Now let's trace this through, let's see how it works. 00:22:57.683 --> 00:23:02.934 There's typical application. I've got some user out there that's that little man standing there 00:23:02.934 --> 00:23:10.518 That's actual real person and that real person is interacting with system through some delivery mechanism. 00:23:10.518 --> 00:23:13.561 Maybe it's the web, maybe it's not, who cares. 00:23:13.561 --> 00:23:25.915 The person, user, pushes some buttons or type on the keyboard or does something that stimulates the system to accept data. 00:23:25.915 --> 00:23:31.619 The delivery mechanism, maybe it's the web, maybe it's something else, it doesn't matter 00:23:31.619 --> 00:23:37.030 Translates that into the creation of something that called request model. 00:23:37.030 --> 00:23:39.844 A Request Model is a pure data structure. 00:23:39.844 --> 00:23:50.698 A Plain Old .Net Object(POCO) or Plain Old Java Object(POJO), a raw data structure it has no idea where data came from there's no trappings of the web 00:23:50.698 --> 00:23:52.764 If there's the trappings of the web anywhere 00:23:52.764 --> 00:23:56.904 It's just a plain old data structure, no methods on it. No nothing. 00:23:56.904 --> 00:24:01.911 Bunch of public elements in a data structure, it contains all the input data 00:24:01.976 --> 00:24:11.846 That gets passed into an interface, the input boundary interface which the interactor derives from 00:24:11.846 --> 00:24:20.717 The interactor receives the requests model and reads it and interprets it 00:24:20.717 --> 00:24:26.778 And turns it into set of smaller commands which it sends to the entities 00:24:26.778 --> 00:24:33.196 All the little business objects out there, it controls the dense of all the methods calls to the entities. 00:24:33.196 --> 00:24:41.673 And once the job is done, then it reverses the flow. And it queries those entities and says, 'OK what happened to you?' 00:24:41.673 --> 00:24:47.942 And there's the result of that it builds up yet another data structure called Result Model. 00:24:47.942 --> 00:25:01.338 Result model is still just a plain old data structure, nothing knew about it, just an old plain .Net or Java object bunch of public fields no methods 00:25:01.338 --> 00:25:11.928 That result model gets passed through the output boundary to the delivery mechanism where gets displayed somehow to the user. 00:25:11.928 --> 00:25:18.006 That's the flow of just any other application. 00:25:18.006 --> 00:25:23.632 Could you test that interactor? 00:25:23.632 --> 00:25:24.772 must be easy wouldn't it? 00:25:24.772 --> 00:25:30.610 Create the input data structure, invoke the interactor look at the output data structure 00:25:30.610 --> 00:25:33.424 Do you have to the web server running to do that? 00:25:33.424 --> 00:25:40.663 No, because the interactor, just plain old Java object or plain old .Net object, so all the data structure 00:25:40.663 --> 00:25:45.237 Do you have to the database running to do that? Well you might. But we'll deal with that in a minute. 00:25:45.237 --> 00:25:50.665 I can test this without the delivery mechanism in place at all 00:25:50.665 --> 00:25:56.218 If my delivery mechanism is the web? I don't care! I don't have to have the web server running? 00:25:56.218 --> 00:25:58.291 I don't have to test it with the web pages. 00:25:58.291 --> 00:26:07.206 I can test the functioning of the system without going all the way from the inputs to the outputs 00:26:12.286 --> 00:26:14.110 What about MVC? 00:26:14.110 --> 00:26:18.936 Isn't MVC the thing we all supposed to doing? 00:26:20.206 --> 00:26:28.683 What is the MVC stands for? Model View Controller. Who invented it? 00:26:28.683 --> 00:26:35.480 That guy. Now I'm going to completely mispronounce his name. You can probably say it better than I 00:26:35.480 --> 00:26:41.514 But I'm gonna call him Trygve Reenskaug. You can probably say it better than me. 00:26:41.514 --> 00:26:47.317 I met him once. This is the guy who invented model view controller in late 1970s. 00:26:47.317 --> 00:26:50.027 I met him once. I met him here at this conference two years ago. 00:26:50.027 --> 00:26:57.378 I was up in speakers lounge and I was hunting for a power outlet And this old guy walks up to me and hands me a power outlet 00:26:57.378 --> 00:27:01.080 I looked up and... Trygve Reenskaug! 00:27:01.080 --> 00:27:07.596 And as he handed me the power outlet our fingers touched! 00:27:07.596 --> 00:27:13.075 I haven' washed that hand. Trygve Reenskaug. 00:27:13.075 --> 00:27:19.293 Some people came up and took their picture with me today. I'm a fan boy too. 00:27:21.423 --> 00:27:27.284 In the early 80s and late 70s, Trygve Reenskaug came up with this structure called model-view-controller. 00:27:27.284 --> 00:27:30.099 He did this in the Smalltalk platform. 00:27:30.099 --> 00:27:33.042 And the idea behind it is very simple. 00:27:33.042 --> 00:27:36.704 You've got a model object, the model object contains the business rules. 00:27:36.704 --> 00:27:41.326 It does not know how it's displayed. It does not know where the input comes from 00:27:41.326 --> 00:27:48.182 It's pure business rules nothing more. There's a controller down there. The controller handles all the input. 00:27:48.182 --> 00:27:59.586 The job of the controller is to look at whatever the input device is, keyboard doesn't matter. And translate the actions of the user into commands to the model. 00:27:59.586 --> 00:28:01.094 Then you've got the View. 00:28:01.094 --> 00:28:06.610 And I've drawn the view with the funny double arrow. That's an Observer relationship. 00:28:06.610 --> 00:28:15.161 The View registers with the model. And whenever the Model is changed it calls back to the View, telling the View to re-display. 00:28:15.201 --> 00:28:25.347 The job of the View is to display or represent or somehow convey the contents of the Model to something else. 00:28:25.347 --> 00:28:35.495 It works nicely on a graphical user interface. It also works just as well on a console device or service oriented architecture or any other kind of application you wish. 00:28:35.495 --> 00:28:40.718 You have something that controls the input, (Controller) something that controls the process (Model) something that controls the output (View) 00:28:40.718 --> 00:28:51.260 This probably the very first named design pattern ever, was meant to be used in the SMALL. 00:28:51.260 --> 00:29:01.770 You would have a model view controller for a button. You would have a model view controller for a checkbox. You would have a model view controller for a text field 00:29:01.770 --> 00:29:05.310 We did not have model view controller for a screen 00:29:06.600 --> 00:29:14.920 Since those early days, this has been twisted and warped and turned because like anything in the software. 00:29:14.920 --> 00:29:23.961 If it turned out to be a good idea, everyone else would copy it. And use the same name for something completely different and call it good. 00:29:23.961 --> 00:29:29.431 This happened with OO It happened with structure It happened with Objects It happened with Agile 00:29:29.431 --> 00:29:37.781 This happened with anything if the name connected with something good, then someone else will connect the name with their stuff and try call it good. 00:29:37.781 --> 00:29:44.013 And that's what happened with MVC now. Nowadays we have these MVC frameworks 00:29:44.013 --> 00:29:50.485 They don't look anything like that. They are not model view controller in the sense of Trygve Reenskaug's model view controller 00:29:50.485 --> 00:29:54.416 They are something very different. In fact, they're kind of look like this. 00:29:55.416 --> 00:30:07.350 Here you've got a bunch of controllers up there. Now the controller, if we think of the web, the controller are somehow activated by the web framework in the sky 00:30:07.350 --> 00:30:12.779 The web framework in the sky, whatever it is, who cares, Rails, Springs God know what 00:30:12.779 --> 00:30:21.848 will somehow route the complicated and horrible URLs that come from the web to a set of functions that we call Controller. 00:30:21.848 --> 00:30:27.079 And it will pass into those controllers the arguments and the data came from the web. 00:30:27.079 --> 00:30:33.950 And those controllers will then reach over and start yelling at the business objects, telling business objects what to do 00:30:33.950 --> 00:30:45.731 Then they'll gather the data from the business objects and talk to the Views. And Views will then reach back into business objects and gather a bunch of data out of them and represent them. 00:30:46.391 --> 00:30:55.422 And what you wind up with are business objects that get polluted with Controller like functions and with View like functions. 00:30:55.422 --> 00:31:05.373 It's hard to know where to put the different function sometime they go into the business objects when they really shouldn't. 00:31:09.133 --> 00:31:13.874 How can we deal with the output side? 00:31:20.086 --> 00:31:32.300 It's gathered the data from the entities the job of the usecases done. The response model has been built. We're about to pass the response model through the output boundary 00:31:15.764 --> 00:31:20.086 Here I show you the interactor. The interactor has done its work 00:31:32.300 --> 00:31:38.262 And what implements that output boundary? Something called Presenter. 00:31:38.262 --> 00:31:44.851 The job of the presenter is to take that response model which, remember, is a pure data structure. 00:31:44.914 --> 00:31:52.427 And translate it into yet another pure data structure, which we would call a View Model. 00:31:52.427 --> 00:32:03.575 The view model is a model of the output, the representation of the output. It still a data structure. 00:32:03.575 --> 00:32:10.685 But if there is a table on the screen, there will be a table in that data structure 00:32:10.753 --> 00:32:17.424 If there is a text field on the screen, there'll be a text field in that data structure 00:32:17.490 --> 00:32:28.201 If the numbers on the screen need to be trimmed to two decimal places, there will be TrimToTwoDecimalPlaces and ConvertIntToStrings in the view model. 00:32:28.201 --> 00:32:37.522 If they have parenthesis around them if they're negative those parenthesis will have been put on them by the Presenter and put into the View Model. 00:32:37.596 --> 00:32:43.097 If there are menu items, names of those menu items are in the View Model. 00:32:43.191 --> 00:32:52.862 If some of those menu items need to be grayed out because they're inactive, there are booleans in the view model that tell you that they should grayed out 00:32:52.862 --> 00:33:05.357 Anything displayable is represented in the view model data structure in a displayable but still abstract way. 00:33:05.357 --> 00:33:08.167 And then that get feds the View. 00:33:08.167 --> 00:33:15.893 And View is stupid. View doesn't have anything to do with, just takes all the fields from the View Model. Put somewhere they have to go. Boom Boom Boom 00:33:15.893 --> 00:33:21.133 No processing, No if statement, it might be a while loop to load up a table. But that's about it. 00:33:21.133 --> 00:33:29.606 The View is too dumb to worry about we don't usually even bother about testing the view. Because we gonna look at it with our eyes on it anyway. 00:33:29.606 --> 00:33:33.069 Can you test that Presenter? 00:33:33.100 --> 00:33:38.321 Yeah! You handed it the data structure with response model. And You look to get the View Model data structure out. 00:33:38.321 --> 00:33:43.797 You can test that Presenter. Do you need the webserver up and running to test Presenter? 00:33:43.844 --> 00:33:48.844 No, You can test all the stuff without webserver running. 00:33:48.844 --> 00:33:53.198 You don't have to fire up Spring or whatever God knows all the container You've got 00:33:53.198 --> 00:33:55.956 You don't know how to fire up all this goop. 00:33:55.956 --> 00:33:59.520 You test all this stuff just like the little old objects 00:33:59.520 --> 00:34:06.612 And by the way that's a goal. You wanna test as much as you can test without firing up anything. 00:34:06.612 --> 00:34:13.095 You don't have to start the server, start that server, start this thing, start this thing which takes 30 seconds to a minute. 00:34:13.095 --> 00:34:21.176 You don't have to any of that. You want to just be able to run your test Just like that boom boom boom boom, fast as you can. 00:34:23.496 --> 00:34:26.049 There's the whole piece. 00:34:26.049 --> 00:34:32.487 From the interactor out, you can see the interactor takes data in from the request model through the input boundary 00:34:32.487 --> 00:34:37.909 delivers data through the output boundary through the response model into the Presenter 00:34:37.909 --> 00:34:48.541 And now look at that black line. That black line is the line that divides the delivery mechanism from the application. 00:34:48.541 --> 00:34:54.756 And notice that every arrow crosses that black line pointing towards the application. 00:34:54.756 --> 00:35:00.046 The applications knows nothing about the controller or the presenter. 00:35:00.046 --> 00:35:04.828 It knows nothing about the web, it knows nothing about what that I/O channel is. 00:35:04.828 --> 00:35:10.755 The I/O channel knows about the application, the applications does not know about the I/O channel. 00:35:10.755 --> 00:35:21.160 If you are to put them in the separate Jar files, there would be no dependence from the application jar file upon the web jar file 00:35:21.160 --> 00:35:30.222 And that also ways to go. You'd like to be able to put them in the separate Jar files. So that you could have a Jar file for the web and a jar file for your application 00:35:30.222 --> 00:35:33.517 And maybe another Jar file for some other I/O mechanism. 00:35:33.517 --> 00:35:38.750 And the way that you would change I/O mechanism is simply swap out the jar files. 00:35:38.750 --> 00:35:50.047 Think of the I/O mechanism, the web, as a plug-in. How many of you use .Net Sharp isn't it? 00:35:50.085 --> 00:35:54.910 You guys all .Net are you? Who's .Net? 00:35:54.910 --> 00:36:04.165 What IDE do you use? Do you have any plug-ins? So a plug-in 00:36:05.885 --> 00:36:14.954 Which of the two authors, the author of the IDE and the author of the Plug-in. Which of the two authos knows about the other? 00:36:17.049 --> 00:36:25.830 The plug-in authors know about the IDE authors. The IDE authors don't know anything about the plug-in authors. 00:36:25.830 --> 00:36:27.668 Don't care. 00:36:27.716 --> 00:36:35.500 Which of the two can harm the other? Can the plug-in author harm VisualStudio? 00:36:35.500 --> 00:36:42.543 Who's using Resharper? Yeh. Can the Resharper guys, JetBrains guys can they harm VisualStudio? 00:36:42.643 --> 00:36:46.554 - (Listeners) Yes, yes - (Robert Martin) Well, they can break it. 00:36:46.554 --> 00:36:52.545 But can they harm it in the way that the authors of VisualStudio must respond to? 00:36:52.545 --> 00:36:58.895 The software developers at Microsoft will they ever respond to JetBrains? 00:36:58.895 --> 00:37:02.410 No, they don't care about JetBrains. 00:37:02.483 --> 00:37:10.232 Can the developers at Microsoft force the developers at JetBrain to respond to them? 00:37:10.232 --> 00:37:13.757 Yeh, Big time! 00:37:13.757 --> 00:37:17.791 Now, think about that in your application's point of view. 00:37:17.791 --> 00:37:25.851 Which parts of your application do you want to be protected from other parts? 00:37:25.851 --> 00:37:34.771 Which parts do you want to be forced to respond the changes in the other and which ones do you not want to be forced to change in response to the other? 00:37:34.771 --> 00:37:38.838 And the answer to the ought to be very very clear. 00:37:38.838 --> 00:37:45.152 You would like to protect your business rules from changes to the web. 00:37:45.152 --> 00:37:49.706 You don't wanna protect the web from changes to the business rules. 00:37:49.706 --> 00:37:59.528 But changes on the web side should have no affect at all on the business rules side and that's what the architecture guarantees you. 00:37:59.528 --> 00:38:06.710 All those dependencies point inward towards the application. Keep that in mind. That is the plug-in architecture. 00:38:07.680 --> 00:38:11.912 Which leads us to the database. 00:38:14.882 --> 00:38:18.116 What about the database? 00:38:20.396 --> 00:38:22.991 Is that your view of the database? 00:38:23.931 --> 00:38:31.846 Do you think of the database is the great god in the center with little minions around outside being applications? 00:38:31.846 --> 00:38:37.573 Does anybody have a job function of DBA? Do we have DBAs in the room? 00:38:37.573 --> 00:38:39.368 Aha I'm safe. Good. 00:38:39.368 --> 00:38:48.993 Anybody know about the DBA? Rolled it over the applications. Panned out the schema. Make sure the database is right. 00:38:49.066 --> 00:38:52.413 Is this how you think about the database? 00:38:52.540 --> 00:38:55.061 Because here's my point. 00:38:55.135 --> 00:38:57.389 The Database is a detail! 00:38:57.389 --> 00:39:00.753 It's not architecturally significant! 00:39:00.885 --> 00:39:05.017 The database is a bucket of bits! 00:39:05.876 --> 00:39:10.112 It is not an architecturally significant element of you system. 00:39:10.112 --> 00:39:12.791 It has nothing to do with business rules. 00:39:12.791 --> 00:39:17.263 God help you if you are putting business rules in the stored procedure. 00:39:17.263 --> 00:39:25.818 What goes in the stored procedure are enhanced queries, validations, integrity checks, but not business rules. 00:39:29.898 --> 00:39:32.519 Why do we have databases? 00:39:34.219 --> 00:39:40.744 Where did this whole database thing come from? Why is there Oracle? 00:39:45.614 --> 00:39:48.768 Where did we store all that data? 00:39:48.768 --> 00:39:53.494 We stored it on spinning disks. Is anybody written a disk driver? 00:39:53.494 --> 00:39:58.375 Anybody written a software that controls memory in and out of spinning disk? 00:39:58.456 --> 00:40:06.569 Nobody! Oh gosh. Oh... Yeah! disk driver! 00:40:06.569 --> 00:40:10.454 What? Diskette? That's good enough! 00:40:10.454 --> 00:40:15.290 So getting data in and off of a disk is hard. Why is it hard? 00:40:15.290 --> 00:40:18.183 Because of the way the data is organized on the disk. 00:40:18.261 --> 00:40:21.820 The way the data is organized on the disk in the circular tracks. 00:40:21.820 --> 00:40:26.055 The circular tracks go around the surface of the platter. There can be many platters. 00:40:26.055 --> 00:40:35.025 There are heads that move in and out to find the track, so you've got to move the head to the right track. 00:40:35.066 --> 00:40:38.941 Then the disk spins around and you've got to read the data off the disk. 00:40:38.941 --> 00:40:46.894 You try get to the sector you want. There might be fifty of sixty sectors around the surface of a track. Each of the sectors might have 4k bytes. 00:40:46.894 --> 00:40:52.282 So you gotta wait for the disks spin around until your sector comes then you gotta read the sector. 00:40:52.282 --> 00:40:57.368 And then you go into that sector and find the byte you want. 00:40:57.368 --> 00:41:01.134 That's a pain. And it's slow. 00:41:01.144 --> 00:41:05.141 And if you don't optimize it can take forever to get anything in and off the disk! 00:41:05.141 --> 00:41:13.866 So we wrote the systems that optimize for that particular problem. We called them databases. 00:41:15.106 --> 00:41:17.502 But somethings happened. 00:41:17.502 --> 00:41:28.339 See my lap top there? My lap top has half of terabyte of Solid State Memory. Doesn't have a disk. That shouldn't be a surprise to you. 00:41:28.339 --> 00:41:30.936 Is anybody have disk in the room? 00:41:30.936 --> 00:41:34.012 Is there a spinning disk in this room? 00:41:34.012 --> 00:41:37.070 Oh my god, really? 00:41:37.070 --> 00:41:43.249 Huh, you know, nowadays we don't even think about spinning disks anymore. We think about Solid State Memory. 00:41:43.249 --> 00:41:50.126 Oh we think back in the server room. There's probably spinning disks. But, there are going away too. 00:41:51.019 --> 00:41:55.998 You watch over next few years. spinning disks begin to disappear. Everything gets replaced with RAM. 00:41:56.081 --> 00:41:59.719 And I said RAM, didn't I? 00:41:59.719 --> 00:42:04.421 RAM is directly addressable at a byte level. 00:42:04.498 --> 00:42:13.672 What we are approaching is a virtually infinite amount of directly addressable RAM that is persistent. 00:42:13.672 --> 00:42:17.634 That's where we are going to be storing our data. 00:42:17.634 --> 00:42:27.902 And if that's where we are going to be storing our data, why in hell would we want to use SQL to access it? 00:42:27.902 --> 00:42:32.101 SQL's pain. Tables are a pain. 00:42:32.101 --> 00:42:36.937 Wouldn't you rather be following pointers around when you rather looking things up in hash tables? 00:42:36.937 --> 00:42:44.662 Isn't that what you do anyway? You read all the tables into memory and then put the data into better organizations You can actually use it? 00:42:44.662 --> 00:42:49.298 What if we just left it in that format that we want to use it? 00:42:49.298 --> 00:42:52.746 If I were Oracle I would be scared to death. 00:42:52.801 --> 00:42:57.280 Because the reason for my existence is disappearing out from underneath. 00:42:57.280 --> 00:43:02.567 The notion of a big database system is beginning to go away. 00:43:05.317 --> 00:43:10.279 How can I protect my application from this detail? 00:43:10.279 --> 00:43:19.105 This detail of database tends to dominate everything and I can protect it the same way I protected my application against the web. 00:43:19.105 --> 00:43:23.129 I draw another one of those nice big heavy black lines. 00:43:23.198 --> 00:43:30.444 And I make sure all the dependencies cross that line going inward towards the applications. 00:43:30.444 --> 00:43:35.554 I make the database a plug-in to the application. 00:43:35.554 --> 00:43:38.924 So that I can swap out Oracle with MySQL 00:43:38.924 --> 00:43:42.706 or I can yank out MySQL and put in CouchDB 00:43:42.706 --> 00:43:47.465 or I can take out CouchDB and put in Datomic or whatever I wish. 00:43:47.465 --> 00:43:50.248 I can plug in the database. 00:43:50.248 --> 00:43:57.116 You may never change the database but it's nice to be able to. Even if you don't have to. 00:43:57.116 --> 00:44:01.082 How do we do it? Well, fairly straight forward, there's another interface up there. 00:44:01.082 --> 00:44:03.062 I called it here the Entity Gateway. 00:44:03.102 --> 00:44:10.159 You probably have one per entity and the methods in the gateway are all the query methods. 00:44:10.159 --> 00:44:14.247 Anything you might query, there's function for, method for 00:44:14.247 --> 00:44:19.247 You implement that method down in the entity gateway implementation below the line. 00:44:19.247 --> 00:44:23.128 And that implementation uses the database whatever it is. 00:44:23.128 --> 00:44:29.917 Notice that no part of the database manages the leak into the application. 00:44:29.917 --> 00:44:39.838 Where the entity objects come from. Well entity objects are probably fetched out of the database although got knows what crazy way they've been spread out in the tables. 00:44:39.838 --> 00:44:44.115 The implementation of entity gateway will gather the data together. 00:44:44.115 --> 00:44:47.673 Create entity objects and then pass them across the line. 00:44:47.673 --> 00:44:53.114 So once you get them above the line, they are real entity objects. 00:44:55.164 --> 00:45:00.283 Guys using something like Hibernate? Some ORM tool? 00:45:00.283 --> 00:45:02.045 Who's using something like that? 00:45:02.066 --> 00:45:06.983 Where would that be in this diagram? 00:45:06.983 --> 00:45:10.485 In the implementation! Below the line! 00:45:10.485 --> 00:45:16.176 No part of that ORM tool would be known above the line. 00:45:16.176 --> 00:45:21.664 Are You using those funny little annotations and attributes in business objects? Get them out of your business objects. 00:45:21.664 --> 00:45:25.465 You dont' want your business objects to know that there are built by Hibernate. 00:45:25.465 --> 00:45:31.817 Let them be built below the line by somebody who's polluted already by the database concept. 00:45:31.831 --> 00:45:36.131 Keep your business objects pure. Why? 00:45:37.741 --> 00:45:40.556 What's an object? 00:45:43.106 --> 00:45:45.360 I've got time for this. 00:45:46.610 --> 00:45:54.363 What's an object? An object is a set of public methods 00:45:54.363 --> 00:46:00.727 And well you are not allowed to know the rest, are you? 00:46:00.727 --> 00:46:04.792 There might be data in there. But you're not allowed to see it. It's all private, isn't it? 00:46:04.792 --> 00:46:11.459 From you point of view, object is bunch of methods. Not a bunch of data. 00:46:11.459 --> 00:46:13.618 And object is a bunch of methods. 00:46:13.618 --> 00:46:17.075 An object is about behavior. 00:46:17.075 --> 00:46:20.863 An object is about business rules. 00:46:20.863 --> 00:46:23.213 It is not about data. 00:46:23.213 --> 00:46:26.228 We presume there's data in there somewhere, but we don't know where. 00:46:26.228 --> 00:46:29.990 And we don't know what formats in it. We don't want to know. 00:46:29.990 --> 00:46:32.973 What is a data structure? 00:46:32.973 --> 00:46:40.606 A data structure is a grouping of well known data elements. Public. Visible to everybody. 00:46:40.606 --> 00:46:42.761 And there's no methods in them. 00:46:42.761 --> 00:46:44.779 Data structures don't have functions. 00:46:44.779 --> 00:46:47.263 These two things are exact opposite of each other. 00:46:47.263 --> 00:46:54.612 A data structure has visible data and no methods. An object has visible functions and no visible data. 00:46:54.612 --> 00:46:56.112 Precisely the opposite. 00:46:56.112 --> 00:47:00.133 There's no such thing as an ORM. 00:47:00.175 --> 00:47:03.339 Object relational mapper? Can't do it. 00:47:03.411 --> 00:47:10.222 Because what comes out of database is a data structure and you cannot map a data structure to an object. 00:47:10.268 --> 00:47:12.452 Cause they are completely different things. 00:47:12.452 --> 00:47:19.613 What's happening here is that the data needed by entities gets put somewhere. God knows where. 00:47:19.613 --> 00:47:26.614 And somehow magically passed to an entity that uses it somehow. And I don't care how. 00:47:26.615 --> 00:47:31.151 Those entities are not constructed by Hibernate. 00:47:31.151 --> 00:47:38.006 Probably those entities use bunch of little data structures that Hibernate did construct but I don't care how. 00:47:38.006 --> 00:47:45.239 I don't want any knowledge of Hibernate or any other framework to cross that black line. 00:47:45.239 --> 00:47:48.358 Stuff below the line can be polluted. 00:47:48.358 --> 00:47:54.559 Above the black line, those are my family jewels. I'm gonna keep them protected. 00:47:54.559 --> 00:48:02.572 Those are my business rules. I'm not going to allow my business rules to be polluted with frameworks. 00:48:02.572 --> 00:48:09.793 Frameworks. We like our frameworks. We think they're cool. 00:48:09.793 --> 00:48:14.859 We think frameworks save us a lot of time and they do. 00:48:14.859 --> 00:48:21.820 But the authors of frameworks entice us to bind to them. 00:48:21.820 --> 00:48:26.278 They offer us base classes for us to inherit from. 00:48:26.278 --> 00:48:32.477 When you inherit from a base class, you marry that class. 00:48:32.477 --> 00:48:40.045 You bind yourself strongly to that base class. There's no relationship stronger than inheritance. 00:48:40.045 --> 00:48:47.430 So by deriving from someone else's base class, you're making a huge commitment to them. 00:48:47.493 --> 00:48:52.156 But they, on the other hand, are not making any kind of commitment to you. 00:48:52.156 --> 00:48:54.684 So it's an asymmetrical relationship. 00:48:54.684 --> 00:49:02.244 The framework author gets the benefit of your commitment. But the framework author makes no commitment to you at all. 00:49:02.305 --> 00:49:06.524 I leave you to make that comparison to yourself. 00:49:06.524 --> 00:49:12.336 A wise architect does not make that binding. 00:49:12.336 --> 00:49:20.705 A wise architect looks at the framework cynically. Looks at and says that framework ought to screw me. 00:49:20.705 --> 00:49:25.605 That framework wants me to bind to it. And I don't think I'm going to. 00:49:25.605 --> 00:49:30.985 I think I'm gonna put boundaries between my business rules and that frameworks. 00:49:30.985 --> 00:49:39.477 So that my business rules are not forever tied to Hibernate or Spring. God know what. 00:49:39.477 --> 00:49:43.966 I'll use the framework. And I'll use the framework carefully. 00:49:43.966 --> 00:49:49.822 Because the author of the framework does not have my best interest at heart. 00:49:55.672 --> 00:50:03.334 Long ago, my son and I and several other people wrote a tool called Fitnesse. 00:50:03.334 --> 00:50:06.533 Is anybody use Fitnesse? Oh bunch of you, good. 00:50:06.533 --> 00:50:13.149 Fitnesse is a tool for writing customer acceptance test. 00:50:13.188 --> 00:50:17.576 It's based on a Wiki and that's really all you need to know it's based on a Wiki. 00:50:17.576 --> 00:50:19.397 Who invented Wiki? 00:50:19.437 --> 00:50:22.483 Ward Cunningham. Who's Ward Cunningham? 00:50:22.483 --> 00:50:26.765 Guy invented Wiki. Ah~ He's a lot more than that. 00:50:26.765 --> 00:50:35.256 Ward Cunningham is one of those Gurus of Gurus. All the Gurus know who Ward Cunningham is. 00:50:35.256 --> 00:50:39.995 All the guys who go around speaking at conferences, like me, we all know who Ward Cunningham is. 00:50:40.028 --> 00:50:42.006 And we review him from on high. 00:50:42.006 --> 00:50:46.424 He was the guy made phone call to Eric Gamma 00:50:46.424 --> 00:50:49.760 Said "You know Eric, you gotta write a book called design patterns." 00:50:49.800 --> 00:50:58.122 This is the guy mentored Ken Beck. Taught him things like Pair Programming and Test Driven Development and Agile Development. 00:50:58.122 --> 00:51:06.937 Ward Cunningham is a one of those guys, if you know a lot about the history of software. You think "Wow he had his hands in everything!" 00:51:06.937 --> 00:51:12.160 Fitnesse is based on two inventions of Ward, the Wiki and Fit. 00:51:12.204 --> 00:51:16.212 I'm not going to describe Fit. I'll describe Wiki however. 00:51:16.212 --> 00:51:24.896 My son and I and bunch of other folks decided to write this in Java about 12 years ago. 13 years ago something like that. 00:51:24.896 --> 00:51:27.807 We knew we wanted make a Wiki. 00:51:27.807 --> 00:51:34.958 And so we thought "Well we got a place to store the pages, let's store them in a database and what database would that be?" 00:51:34.992 --> 00:51:41.925 Well back in those days the only opensource database was MySQL. So we decided put everything in MySQL. 00:51:43.245 --> 00:51:50.880 And we were about to go fire up MySQL and start building a schema and somebody said. 00:51:50.880 --> 00:51:53.550 "You know we don't really have to do that. Right yet" 00:51:53.550 --> 00:51:58.793 "I mean we will later but not right now because we can get away right now with another problem" 00:51:58.793 --> 00:52:03.312 And that problem was translating Wiki text to HTML. That's what Wiki does. 00:52:03.382 --> 00:52:07.185 Takes the funny text you typed into the Wiki and turns it into HTML. 00:52:07.251 --> 00:52:10.156 And there was a lot of that translation that we needed to do. 00:52:10.156 --> 00:52:14.258 So about 3 month we just forgot about the database altogether. 00:52:14.258 --> 00:52:21.379 And we translated Wiki text to HTML. We needed an object for this which we called WikiPage. 00:52:21.414 --> 00:52:22.968 You can see it here. 00:52:22.968 --> 00:52:29.995 We created an abstract class named WikiPage and we implemented it with something called MockWikiPage. 00:52:29.995 --> 00:52:37.446 The methods of WikiPage had database like funtions such as Load and Save. 00:52:37.490 --> 00:52:40.028 But they were unimplemented. The didn't do anything. 00:52:40.028 --> 00:52:43.364 And for about three months we worked that way. 00:52:43.364 --> 00:52:49.177 Once we had all the translation done. Then we said "Well it's time to fire up the database." 00:52:49.177 --> 00:52:52.039 "Cause now we need to actually store these pages somewhere" 00:52:52.070 --> 00:52:54.670 And somebody said "Well, we don't need to do that yet." 00:52:54.670 --> 00:53:00.006 "Because what we could do instead is take this pages and store them in a hash tables in RAM." 00:53:00.056 --> 00:53:02.590 "I mean we don't really need to store them on disk yet, do we?" 00:53:02.590 --> 00:53:06.356 The answer to that was no. Cause all we were doing was writing unit test anyway. 00:53:06.356 --> 00:53:14.871 So we decided to create a another version of the Wiki page called the InMemoryPage which stored all the data in hash tables. 00:53:14.871 --> 00:53:17.436 And we continued to work for a year. 00:53:17.786 --> 00:53:21.611 Continuing to write more and more Fitnesse keeping all the data in memory. 00:53:21.611 --> 00:53:24.294 We actually got all of Fitnesse working. 00:53:24.744 --> 00:53:27.280 Without ever putting it into a disk. 00:53:27.332 --> 00:53:32.169 And it was very cool because all the test went really fast. No database. 00:53:32.169 --> 00:53:38.712 On the other hand it was frustrating because we would created a bunch of tests and shut the computer down and then all be gone. 00:53:38.712 --> 00:53:44.721 So it's some point we finally said "Well now it's the time for database, let's fire up MySQL." 00:53:44.721 --> 00:53:46.664 And Michael Feathers was there at that time. 00:53:46.664 --> 00:53:50.274 And Michael said "Well you don't really have to fire up MySQL yet." 00:53:50.350 --> 00:53:58.620 "All you really need is persistence. And you can get that persistency really cheaply by taking the hash tables to be written into flat files." 00:53:59.260 --> 00:54:06.860 And we thought that's kind of ugly but it'll work for the time being. And then later on we'll switch it all over MySQL. So we did that. 00:54:06.860 --> 00:54:11.112 And for another 3 months we continued to develop more and more about Fitnesse. 00:54:11.112 --> 00:54:16.374 And that was kind of cool. Cause we could take on the road. We could show it to people. We could save pages. 00:54:16.426 --> 00:54:18.278 Started work like real Wiki. 00:54:18.551 --> 00:54:27.959 About 3 months after that we said "We don't need that database" 00:54:28.539 --> 00:54:31.807 "It's working fine! Flat files are fast enough." 00:54:31.879 --> 00:54:33.691 "Works okay, that way." 00:54:33.732 --> 00:54:38.884 We took that highly significant architectural decision and pushed it off to the end of planet. 00:54:38.884 --> 00:54:43.799 We never put that database in. That's not quite true actually. Somebody else did. 00:54:44.249 --> 00:54:49.745 A customer of ours came along little latter and said "I gotta have the data in database." 00:54:49.745 --> 00:54:52.371 We said "But why? It's working fine in the flat file" 00:54:52.495 --> 00:54:59.032 He said "Corporate policy, all corporate assets must be in a database." 00:54:59.032 --> 00:55:04.115 I don't know who they'd been talking to. But these database salesman were pretty convincing. 00:55:04.415 --> 00:55:11.854 So, we said "Well Look. If you really needed it in a database." 00:55:13.624 --> 00:55:24.208 "Here's this structure all you have to do is create a new derivative called MySQL page. And everything ought to work fine." 00:55:24.251 --> 00:55:27.162 And he came back a day latter and the whole thing running MySQL. 00:55:27.162 --> 00:55:31.468 We used to ship that as a plug-in but nobody ever used it so we stopped. 00:55:32.018 --> 00:55:37.936 Here's an architectural decision that we deferred and deferred and delayed and delayed. 00:55:38.003 --> 00:55:41.034 We delayed right up to the end of project. Ne never did it. 00:55:41.034 --> 00:55:45.352 Something that we thought we had to do it first, we never did it. 00:55:45.352 --> 00:55:49.120 That leads to the final principle. 00:55:50.619 --> 00:56:00.209 A good architecture is an architecture that allows major decisions to be delayed! Deferred! 00:56:00.209 --> 00:56:05.107 The goal of an architect is to not make decisions. 00:56:05.147 --> 00:56:12.618 To delay those decisions as long as possible so that you have the most information with which to make them. 00:56:12.618 --> 00:56:21.953 You structure design and the high level structure of your code so that all these high level decisions can be pushed off. 00:56:21.953 --> 00:56:28.929 Don't tell me that the architecture of your application is a bunch of frameworks. 00:56:28.970 --> 00:56:35.568 "What's the architecture of your application? Yeah, we're using a SQL server and MVVM and blah.. " 00:56:35.568 --> 00:56:37.347 You're not telling me anything. 00:56:37.347 --> 00:56:40.744 You're telling me the tools. 00:56:40.744 --> 00:56:43.011 That's not the architecture of your application. 00:56:43.075 --> 00:56:46.104 The architecture of your applications are the usecases. 00:56:46.104 --> 00:56:50.460 And you want your usecases to not know about those tools. 00:56:50.460 --> 00:56:54.847 You wanna be able to defer the use of those tools for as long as possible. 00:56:54.847 --> 00:57:02.270 You should be able to have the whole application running without ever firing up a database, without ever firing up the web. 00:57:02.270 --> 00:57:07.483 Or maybe you fire up some gunky little web thing that you can toast together in a day or two. 00:57:07.483 --> 00:57:12.177 Just so that you can see some pages without firing up some gigantic framework. 00:57:12.177 --> 00:57:17.485 Maybe you fire up some dumb little database thing just so that you can see some persistence running. 00:57:17.485 --> 00:57:23.627 Without ever having a license of Oracle and all the nonsense you have to go through to get that running. 00:57:25.347 --> 00:57:34.497 Next time you have a application to write, think about what you can delay. 00:57:37.757 --> 00:57:48.049 The application of a system should a plug-in architecture. The architecture of a system should be a plug-in architecture. 00:57:48.083 --> 00:57:55.076 Well all of the details like the UI, the databse, the frameworks plug in to the usecases. 00:57:55.076 --> 00:57:57.959 Which are the real core of your application. 00:57:59.809 --> 00:58:03.990 Now of course, customers are gonna wanna see web pages. 00:58:03.990 --> 00:58:10.463 Okay, you can stil make a plug-in architecture and show them web pages running. 00:58:10.514 --> 00:58:13.339 You don't have to make a lot of commitments to the frameworks. 00:58:13.339 --> 00:58:16.647 You don't have to make a lot of commitments to the web framework. 00:58:16.647 --> 00:58:19.084 You can probably put something simple up it first. 00:58:19.084 --> 00:58:25.807 Or if you want actually use a real framework, fine go ahead. But maintain the plug-in structure. 00:58:25.807 --> 00:58:29.285 So that at a moment's notice you can unplug it and plug something else in. 00:58:31.245 --> 00:58:35.177 And that probably brings to me the end of my talk. 00:58:35.857 --> 00:58:39.417 I already talked about that earlier. (TDD) 00:58:41.737 --> 00:58:45.463 So thank you all very much. are there any questions? 00:58:47.635 --> 00:58:50.950 Very difficult to see, so I'm gonna come down here. 00:58:54.550 --> 00:58:56.664 Oh that doesn't help at all. 00:58:57.464 --> 00:59:01.372 Okay, anybody have any questions? 00:59:01.372 --> 00:59:04.449 You gonna have to like hollow. Because I won't be able to see your hands up. 00:59:04.449 --> 00:59:05.236 Yep. 00:59:05.236 --> 00:59:11.963 (Someone is asking a question) 00:59:11.963 --> 00:59:21.120 So I'm speculating the demise of Oracle and relational databases. What do I suggest to will replace them? 00:59:21.151 --> 00:59:24.337 What an interesting question! 00:59:24.337 --> 00:59:30.947 It could be nothing more than RAM. Why do you need anything to replace them? 00:59:30.947 --> 00:59:36.511 If you gonna organize the data in RAM and if that RAM is persistent, what else do you need? 00:59:36.562 --> 00:59:38.857 Oh but let's say you need something. 00:59:38.857 --> 00:59:41.488 Okay what might it look like? 00:59:42.458 --> 00:59:45.557 Well, who's heard of the CQRS? 00:59:46.437 --> 00:59:47.719 Oh yeah, few of you. 00:59:47.719 --> 00:59:49.933 CQRS, what an interesting idea? 00:59:49.957 --> 00:59:54.999 If we have infinite amount of high speed memory. High speed RAM. 00:59:54.999 --> 00:59:58.390 Or maybe it's even disk but who cares. 00:59:58.390 --> 01:00:02.369 Why would we store the state of anything. 01:00:02.369 --> 01:00:05.195 Why wouldn't we simply store the transactions? 01:00:05.195 --> 01:00:12.043 Instead of storing a bank account, Why wouldn't we store the transactions that caused us to create the bank account. 01:00:12.043 --> 01:00:19.295 The transactions that forced us to change the name in the bank account or the address of the bank account or the balance in the bank account. 01:00:19.295 --> 01:00:23.381 Why wouldn't we store the transactions and reconstruct the state. 01:00:23.381 --> 01:00:25.870 And you say to yourself "Well it will take a lot of time" 01:00:25.870 --> 01:00:28.512 Yeah, but we've lots of processing power. 01:00:28.512 --> 01:00:35.131 We can do that now, we have almost infinite amount of processing power and almost infinite amount RAM. 01:00:40.331 --> 01:00:44.299 Why wouldn't we store just the events? 01:00:44.299 --> 01:00:46.264 And I think that's an interesting idea. 01:00:46.296 --> 01:00:53.412 If we store just events, then we would never delete anything. 01:00:53.412 --> 01:00:55.640 We would never update anything. 01:00:55.709 --> 01:00:59.436 You know CRUD? Create. Read. Update. Delete? 01:00:59.436 --> 01:01:04.702 We'd loose the last 2 letters there. All our applications would be CR. 01:01:04.702 --> 01:01:08.752 Create and Read. We would never update. We would never delete. 01:01:08.752 --> 01:01:13.568 And when you don't update and you don't delete you don't need transactions. 01:01:13.568 --> 01:01:17.292 There can't be any concurrent update problems if you're not updating. 01:01:17.292 --> 01:01:20.151 That's interesting! 01:01:20.151 --> 01:01:25.436 Are there frameworks out there that allow you to do things like that? There are. 01:01:25.468 --> 01:01:27.139 There are number of them out there. 01:01:27.139 --> 01:01:31.633 That are write only databases. Write once and read many times. 01:01:32.703 --> 01:01:35.381 You can find them on the web. I'm not gonna tell you the names right now. 01:01:35.381 --> 01:01:37.632 But you can go out there and look for them. There are out there. 01:01:37.632 --> 01:01:40.162 You might replace them something like that. 01:01:40.162 --> 01:01:45.731 You might replace them with Couch or Mongo. Or you might create some other thing. 01:01:45.778 --> 01:01:51.519 It really doesn't matter. You don't have to have some massive vendor offering. 01:01:51.583 --> 01:01:53.852 From some gigantic company in the sky. 01:01:53.852 --> 01:01:58.568 That blesses you and says "Yes son, you may use my database system." 01:02:00.218 --> 01:02:02.967 Maybe you can just make your own. Not that hard. 01:02:02.967 --> 01:02:04.775 Anybody else? 01:02:07.625 --> 01:02:09.379 Yeah, that actually helps a lot. 01:02:09.379 --> 01:02:12.216 Okay, anybody else with questions? 01:02:15.066 --> 01:02:27.373 (Someone is asking a question) 01:02:27.373 --> 01:02:31.933 Differing decisions does not work very well when.. 01:02:33.923 --> 01:02:42.383 When you have a family? (People laughing) 01:02:43.633 --> 01:02:47.074 You mean in general. There are decisions you can differ. 01:02:47.074 --> 01:02:49.872 For example, what language we gonna write this thing in? 01:02:49.872 --> 01:02:52.603 You gonna have to make that decision pretty early. 01:02:52.603 --> 01:02:56.085 Right? Cause you know you gotta write some. 01:02:56.085 --> 01:03:02.232 The fact that you're going to have a database, probably something you gonna have to make a decision on pretty early. 01:03:02.232 --> 01:03:06.887 The fact that it's gonna be a web application, well you probably have to make that fairly early. 01:03:06.887 --> 01:03:09.262 You have to commit to framework. No. 01:03:09.752 --> 01:03:13.585 A family vacation that's what you were saying here. 01:03:13.585 --> 01:03:22.817 We could plan out where we were going. Would we have to also plan out which car we would use? 01:03:23.467 --> 01:03:31.163 If we're planning a six month in advance, we might decide buy whole new car just for the heck of it? 01:03:31.206 --> 01:03:36.086 Maybe our car break down in the middle. Or before we go on the vacation. 01:03:36.086 --> 01:03:43.321 The car itself is just a vehicle, it doesn't matter as long as our luggage fits in it. And our family. 01:03:43.321 --> 01:03:44.936 We can still go on the vacation. 01:03:44.936 --> 01:03:53.693 The database system is like the car. We don't need to make that decision as part of vacation plan. 01:03:55.893 --> 01:03:59.233 That one can be differed to the last minute. 01:03:59.233 --> 01:04:03.986 You could buy a new car the last minute, the day before you decide to go on vacation. 01:04:04.031 --> 01:04:05.521 And why would you do that? 01:04:05.561 --> 01:04:09.075 You might have gotten a race. You might have more money. 01:04:09.075 --> 01:04:12.391 You might have a baby. Need more space. 01:04:12.441 --> 01:04:17.674 A lot of reason you might wanna buy that car at the last minute. 01:04:18.904 --> 01:04:20.818 Anybody else? 01:04:21.862 --> 01:04:24.136 Yeah, way back there. 01:04:24.136 --> 01:04:29.320 (Someone is asking question) 01:04:29.320 --> 01:04:31.535 How do you deal with legacy architecture? 01:04:31.535 --> 01:04:34.765 Okay, that's gonna take me more than a minute. 01:04:36.205 --> 01:04:40.168 So I'm gonna use one word to answer that question and I'll explain that word. 01:04:40.261 --> 01:04:41.959 Incrementalism. 01:04:42.249 --> 01:04:48.166 Everybody faced with legacy code wants to throw it away and write it over. 01:04:48.198 --> 01:04:50.189 Please don't do this. 01:04:50.759 --> 01:04:56.185 They generally fails, Horribly you'll spend tremendous amount of money and waste a load of time. 01:04:56.185 --> 01:04:58.463 Take little bits of it. 01:04:58.463 --> 01:05:01.495 And rewrite those tiny little bits one at a time. 01:05:01.495 --> 01:05:04.145 And get them working one little bit at a time. 01:05:04.145 --> 01:05:08.029 That will leave you with a patch work. But the patch work will be cleaner than the original. 01:05:08.029 --> 01:05:12.065 And then start over and start re-implementing the patch work. 01:05:12.065 --> 01:05:17.045 Gradually cleaning it making it better and better. It'll take you long time, a lot of effort. 01:05:17.045 --> 01:05:20.421 You wanna do that while you also adding new features. 01:05:20.421 --> 01:05:23.928 In fact, that's just generally cleaning your code. 01:05:23.928 --> 01:05:27.915 Please don't try the big re-design. You'll get hurt. 01:05:28.022 --> 01:05:32.956 Thank you all for your attention. I'll see you another time.