1 00:00:00,000 --> 00:04:43,738 (The talk starts at 4:45) 2 00:04:46,478 --> 00:04:50,376 Alright you all hear me okay? 3 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 4 00:04:56,401 --> 00:05:00,828 Um what is an electron? 5 00:05:04,013 --> 00:05:07,984 So part of atom, everybody knows that, I think 6 00:05:08,290 --> 00:05:17,718 It's um.. (Screams from other room) yeah I think so, . I think that's royal ??? 7 00:05:19,734 --> 00:05:22,415 Electron is part of atom 8 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 9 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 10 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 11 00:05:55,041 --> 00:05:58,778 Why do we think of it as particle? 12 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 13 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 14 00:06:16,418 --> 00:06:21,498 It moves as a wave and the wave has no location 15 00:06:21,498 --> 00:06:27,334 You look at an ocean wave, and ocean wave can be huge 16 00:06:27,334 --> 00:06:33,819 It has no distinct location it has a well defined energy but no distinct location 17 00:06:33,819 --> 00:06:36,450 This is how an electron moves 18 00:06:36,450 --> 00:06:42,191 Electrons obey a principle and it's a mistruster principle 19 00:06:42,191 --> 00:06:45,566 It's called the poly exclusion principle 20 00:06:45,566 --> 00:06:53,202 Two electrons bound into the same system will not be in the same state 21 00:06:53,202 --> 00:06:57,328 For whatever reason they cannot be in the same state 22 00:06:57,328 --> 00:07:00,677 so if there are two electrons in an atom 23 00:07:00,677 --> 00:07:04,066 those two electrons must be different somehow 24 00:07:04,066 --> 00:07:07,709 Now they might different in the direction of their spin 25 00:07:07,709 --> 00:07:10,899 An electron can spin to the left or spin to the right 26 00:07:10,899 --> 00:07:18,355 Two electrons that have exactly same energy could fit together spinning one left and one right 27 00:07:18,355 --> 00:07:21,442 There's no way to get a third one in there 28 00:07:21,450 --> 00:07:28,412 So the next electron must have higher energy and then you can have two more 29 00:07:28,412 --> 00:07:30,806 One spinning left one spinning right 30 00:07:30,806 --> 00:07:34,769 But if you wanted to add another that would have to be something different about them 31 00:07:34,769 --> 00:07:37,917 And you could arrange them differently in space 32 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. 33 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 34 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 35 00:08:07,827 --> 00:08:12,868 Have you ever thought about water? 36 00:08:12,868 --> 00:08:16,880 I got some here. Fascinating substance 37 00:08:16,880 --> 00:08:19,898 What's it made of? 38 00:08:20,484 --> 00:08:25,082 Two hydrogen atoms one oxygen atom that's what makes a water molecule 39 00:08:25,472 --> 00:08:28,076 And what's it shaped like? 40 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 41 00:08:33,482 --> 00:08:42,437 The angle there is the result of (??) the shell arrangement. 42 00:08:42,437 --> 00:08:46,772 What makes the hydrogen and oxygen stick together? 43 00:08:46,772 --> 00:08:51,162 Think of two atoms, two atoms covered by electrons, two electrons are parallel each other 44 00:08:51,162 --> 00:08:56,287 What would make two hydrogens and an oxygen stick together? 45 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 46 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? 47 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 48 00:09:20,400 --> 00:09:25,099 So they will congregate those electron waves will congregate more 49 00:09:25,099 --> 00:09:30,861 Between two atoms, between three atoms actually, then everywhere else 50 00:09:30,861 --> 00:09:34,964 They still go everywhere else that just that more likely to be between them 51 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 52 00:09:47,718 --> 00:09:54,029 Now if you take this Mickey mouse atom and you divide it in half 53 00:09:54,136 --> 00:09:57,675 You find there's more negative charge above the one and below the one 54 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 55 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 56 00:10:08,075 --> 00:10:10,676 It is negative one side and positive on the other 57 00:10:10,676 --> 00:10:12,702 This is why water is wet. 58 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 59 00:10:20,463 --> 00:10:22,614 Even though it is not very electrically charged 60 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 61 00:10:33,772 --> 00:10:37,394 This is why water makes it a good cleanser 62 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? 63 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 64 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 65 00:11:02,317 --> 00:11:06,252 As all the water molecules turn around get it tracked the electric charge 66 00:11:06,252 --> 00:11:09,585 Of course that's not what we supposed to be talking about 67 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. 68 00:11:20,057 --> 00:11:28,490 It's about the next step after clean code after clean design. 69 00:11:28,535 --> 00:11:33,876 This is about clean system structure 70 00:11:33,876 --> 00:11:38,162 And it begins with that 71 00:11:38,162 --> 00:11:47,069 This is a directory structure of an application I wrote close to ten years ago now 72 00:11:47,069 --> 00:11:53,089 I was studying Rails. Anybody here Ruby programmer, Ruby on Rails programmer? 73 00:11:53,089 --> 00:11:56,906 We got a guy over there, waving his hand around. OK. 74 00:11:57,047 --> 00:12:04,404 I was learning Rails at that time. And I wrote this application 75 00:12:04,404 --> 00:12:09,735 And it was I followed the book. You get the books out. You follow the book 76 00:12:09,767 --> 00:12:13,839 Follow all the recommendations of the book and that's what I wound up with 77 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. 78 00:12:20,140 --> 00:12:27,376 Then about three years ago. My son, at my request, wrote an application. 79 00:12:27,376 --> 00:12:32,325 And I looked it in and I saw that. 80 00:12:32,325 --> 00:12:36,174 Same directory structure. 81 00:12:36,174 --> 00:12:40,573 These are two completely different applications. It had nothing to do with each other. 82 00:12:40,614 --> 00:12:45,121 But they had same directory structure. And I looked at it and I thought. 83 00:12:45,121 --> 00:12:52,868 Wait why did these two applications have the same high level structure? 84 00:12:52,868 --> 00:12:56,646 They are two completely different applications. 85 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. 86 00:13:02,958 --> 00:13:09,304 And I asked my self, okay but why is that important? 87 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? 88 00:13:20,726 --> 00:13:25,183 And the reason I asset question of myself was because of this. 89 00:13:25,986 --> 00:13:34,191 The web is a delivery mechanism. The web is an I/O channel. 90 00:13:34,191 --> 00:13:37,913 The web is not architecturally significant. 91 00:13:37,980 --> 00:13:42,263 We think of ourselves as writing web applications. 92 00:13:42,263 --> 00:13:44,786 We are not writing web applications. 93 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. 94 00:13:51,940 --> 00:13:57,675 And why should that I/O channel dominate us? 95 00:13:59,785 --> 00:14:06,705 Does anybody remember when the web became important? 1980? 1990? 96 00:14:06,705 --> 00:14:13,833 Anybody remember what a change that was? How radically different everything was? 97 00:14:13,833 --> 00:14:19,872 Except that it wasn't. Because we weren't really doing anything new? 98 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. 99 00:14:26,573 --> 00:14:28,374 That's all the web is. 100 00:14:28,374 --> 00:14:31,082 Why would web dominate so much? 101 00:14:31,082 --> 00:14:39,189 So I started to thinking about architecture. And I started to looking at blue prints. 102 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. 103 00:14:49,599 --> 00:14:51,729 Because it's obviously a library. 104 00:14:51,805 --> 00:14:55,882 You got a bunch of book shelves in there. You got a bunch of reading tables. 105 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 106 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." 107 00:15:11,167 --> 00:15:15,704 Or here's another one. That's a church. It's obviously a church. 108 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. 109 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 110 00:15:29,736 --> 00:15:31,703 This is clearly a church. 111 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. 112 00:15:42,315 --> 00:15:49,020 Their intent. Architecture is about intent. 113 00:15:49,020 --> 00:15:56,016 And the high level structures of those Rails apps were not communicating intent to me. 114 00:15:56,154 --> 00:16:03,104 They were telling me that they were Rails apps. Something wrong with that. 115 00:16:03,104 --> 00:16:05,902 And then it occurred to me. 116 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. 117 00:16:15,087 --> 00:16:20,638 Who got this book? Anybody read this one? I got a guy here, anybody else? 118 00:16:20,677 --> 00:16:23,431 Object-Oriented Software Engineering, if you have. Wonderful Book. 119 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. 120 00:16:29,916 --> 00:16:37,212 Notice the subtitle, the subtitle says "A usecase driven approach" 121 00:16:37,212 --> 00:16:45,107 Who remembers usecases? Uh.. See? It was very popular in the early 90s. big big deal. 122 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. 123 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. 124 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. 125 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 126 00:17:23,318 --> 00:17:29,726 and primary actor and secondary actors and the (???) actor. What the hell is the (???) actor? 127 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. 128 00:17:38,306 --> 00:17:44,214 And right about the peak of the era, the agile movement began. 129 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. 130 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. 131 00:17:58,310 --> 00:18:02,105 And I remembered what Jacobson wrote. 132 00:18:02,168 --> 00:18:11,409 Here is a usecase. Typical of the kind of usecase that Jacobson would have written. 133 00:18:11,444 --> 00:18:15,646 If you notice that it has very little form. 134 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. 135 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. 136 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. 137 00:18:37,657 --> 00:18:40,146 Whether it is a number or string, I don't care. 138 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. 139 00:18:48,328 --> 00:18:51,560 I'm not trying to specify the detail here. 140 00:18:51,599 --> 00:18:55,268 And then you've got the primary course. 141 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. (??) 142 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. 143 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. 144 00:19:18,575 --> 00:19:23,542 Third step is system creates the order and determines the order Id. 145 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. 146 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. 147 00:19:35,106 --> 00:19:40,426 In fact, this whole usecase says nothing about the web. 148 00:19:40,426 --> 00:19:44,456 This usecase would work no matter what the input output channel was. 149 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. 150 00:19:53,606 --> 00:19:59,609 Because the usecase is agnostic, it doesn't care about the I/O channel. 151 00:19:59,609 --> 00:20:09,559 Jacobson said you can take that usecase and turn it into object. 152 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. 153 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. 154 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. 155 00:20:38,028 --> 00:20:45,857 And it implements at least the high level. The rules, the processing steps of the usecase 156 00:20:45,857 --> 00:20:54,166 Notice there's the caption below there. It says interactors have application specific business rules 157 00:20:54,166 --> 00:20:56,768 There are two kinds of business rules 158 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 159 00:21:06,166 --> 00:21:11,695 And then there are other business rules that are tied to the application you're writing 160 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 161 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 162 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 163 00:21:40,739 --> 00:21:47,910 So usecases are application specific, they're bounded to the particular application they're in 164 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 165 00:21:56,727 --> 00:22:01,325 I don't like the term, entity objects that's what Jacobson called them as well 166 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. 167 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 168 00:22:17,332 --> 00:22:24,159 We do that in this case with interfaces. I have drawn these as object-oriented interfaces 169 00:22:24,159 --> 00:22:31,266 And notice that the interactor uses one of the interfaces and derives from the other. 170 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 171 00:22:38,233 --> 00:22:42,174 Notice that the arrows point the same direction, that's important 172 00:22:42,174 --> 00:22:45,106 We'll come to why that's important in a minute 173 00:22:45,106 --> 00:22:53,455 So these are the three objects the Jacobson identified as part of his architecture for applications 174 00:22:53,455 --> 00:22:57,683 Now let's trace this through, let's see how it works. 175 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 176 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. 177 00:23:10,518 --> 00:23:13,561 Maybe it's the web, maybe it's not, who cares. 178 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. 179 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 180 00:23:31,619 --> 00:23:37,030 Translates that into the creation of something that called request model. 181 00:23:37,030 --> 00:23:39,844 A Request Model is a pure data structure. 182 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 183 00:23:50,698 --> 00:23:52,764 If there's the trappings of the web anywhere 184 00:23:52,764 --> 00:23:56,904 It's just a plain old data structure, no methods on it. No nothing. 185 00:23:56,904 --> 00:24:01,911 Bunch of public elements in a data structure, it contains all the input data 186 00:24:01,976 --> 00:24:11,846 That gets passed into an interface, the input boundary interface which the interactor derives from 187 00:24:11,846 --> 00:24:20,717 The interactor receives the requests model and reads it and interprets it 188 00:24:20,717 --> 00:24:26,778 And turns it into set of smaller commands which it sends to the entities 189 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. 190 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?' 191 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. 192 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 193 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. 194 00:25:11,928 --> 00:25:18,006 That's the flow of just any other application. 195 00:25:18,006 --> 00:25:23,632 Could you test that interactor? 196 00:25:23,632 --> 00:25:24,772 must be easy wouldn't it? 197 00:25:24,772 --> 00:25:30,610 Create the input data structure, invoke the interactor look at the output data structure 198 00:25:30,610 --> 00:25:33,424 Do you have to the web server running to do that? 199 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 200 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. 201 00:25:45,237 --> 00:25:50,665 I can test this without the delivery mechanism in place at all 202 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? 203 00:25:56,218 --> 00:25:58,291 I don't have to test it with the web pages. 204 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 205 00:26:12,286 --> 00:26:14,110 What about MVC? 206 00:26:14,110 --> 00:26:18,936 Isn't MVC the thing we all supposed to doing? 207 00:26:20,206 --> 00:26:28,683 What is the MVC stands for? Model View Controller. Who invented it? 208 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 209 00:26:35,480 --> 00:26:41,514 But I'm gonna call him Trygve Reenskaug. You can probably say it better than me. 210 00:26:41,514 --> 00:26:47,317 I met him once. This is the guy who invented model view controller in late 1970s. 211 00:26:47,317 --> 00:26:50,027 I met him once. I met him here at this conference two years ago. 212 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 213 00:26:57,378 --> 00:27:01,080 I looked up and... Trygve Reenskaug! 214 00:27:01,080 --> 00:27:07,596 And as he handed me the power outlet our fingers touched! 215 00:27:07,596 --> 00:27:13,075 I haven' washed that hand. Trygve Reenskaug. 216 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. 217 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. 218 00:27:27,284 --> 00:27:30,099 He did this in the Smalltalk platform. 219 00:27:30,099 --> 00:27:33,042 And the idea behind it is very simple. 220 00:27:33,042 --> 00:27:36,704 You've got a model object, the model object contains the business rules. 221 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 222 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. 223 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. 224 00:27:59,586 --> 00:28:01,094 Then you've got the View. 225 00:28:01,094 --> 00:28:06,610 And I've drawn the view with the funny double arrow. That's an Observer relationship. 226 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. 227 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. 228 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. 229 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) 230 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. 231 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 232 00:29:01,770 --> 00:29:05,310 We did not have model view controller for a screen 233 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. 234 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. 235 00:29:23,961 --> 00:29:29,431 This happened with OO It happened with structure It happened with Objects It happened with Agile 236 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. 237 00:29:37,781 --> 00:29:44,013 And that's what happened with MVC now. Nowadays we have these MVC frameworks 238 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 239 00:29:50,485 --> 00:29:54,416 They are something very different. In fact, they're kind of look like this. 240 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 241 00:30:07,350 --> 00:30:12,779 The web framework in the sky, whatever it is, who cares, Rails, Springs God know what 242 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. 243 00:30:21,848 --> 00:30:27,079 And it will pass into those controllers the arguments and the data came from the web. 244 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 245 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. 246 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. 247 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. 248 00:31:09,133 --> 00:31:13,874 How can we deal with the output side? 249 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 250 00:31:15,764 --> 00:31:20,086 Here I show you the interactor. The interactor has done its work 251 00:31:32,300 --> 00:31:38,262 And what implements that output boundary? Something called Presenter. 252 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. 253 00:31:44,914 --> 00:31:52,427 And translate it into yet another pure data structure, which we would call a View Model. 254 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. 255 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 256 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 257 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. 258 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. 259 00:32:37,596 --> 00:32:43,097 If there are menu items, names of those menu items are in the View Model. 260 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 261 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. 262 00:33:05,357 --> 00:33:08,167 And then that get feds the View. 263 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 264 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. 265 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. 266 00:33:29,606 --> 00:33:33,069 Can you test that Presenter? 267 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. 268 00:33:38,321 --> 00:33:43,797 You can test that Presenter. Do you need the webserver up and running to test Presenter? 269 00:33:43,844 --> 00:33:48,844 No, You can test all the stuff without webserver running. 270 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 271 00:33:53,198 --> 00:33:55,956 You don't know how to fire up all this goop. 272 00:33:55,956 --> 00:33:59,520 You test all this stuff just like the little old objects 273 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. 274 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. 275 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. 276 00:34:23,496 --> 00:34:26,049 There's the whole piece. 277 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 278 00:34:32,487 --> 00:34:37,909 delivers data through the output boundary through the response model into the Presenter 279 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. 280 00:34:48,541 --> 00:34:54,756 And notice that every arrow crosses that black line pointing towards the application. 281 00:34:54,756 --> 00:35:00,046 The applications knows nothing about the controller or the presenter. 282 00:35:00,046 --> 00:35:04,828 It knows nothing about the web, it knows nothing about what that I/O channel is. 283 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. 284 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 285 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 286 00:35:30,222 --> 00:35:33,517 And maybe another Jar file for some other I/O mechanism. 287 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. 288 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? 289 00:35:50,085 --> 00:35:54,910 You guys all .Net are you? Who's .Net? 290 00:35:54,910 --> 00:36:04,165 What IDE do you use? Do you have any plug-ins? So a plug-in 291 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? 292 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. 293 00:36:25,830 --> 00:36:27,668 Don't care. 294 00:36:27,716 --> 00:36:35,500 Which of the two can harm the other? Can the plug-in author harm VisualStudio? 295 00:36:35,500 --> 00:36:42,543 Who's using Resharper? Yeh. Can the Resharper guys, JetBrains guys can they harm VisualStudio? 296 00:36:42,643 --> 00:36:46,554 - (Listeners) Yes, yes - (Robert Martin) Well, they can break it. 297 00:36:46,554 --> 00:36:52,545 But can they harm it in the way that the authors of VisualStudio must respond to? 298 00:36:52,545 --> 00:36:58,895 The software developers at Microsoft will they ever respond to JetBrains? 299 00:36:58,895 --> 00:37:02,410 No, they don't care about JetBrains. 300 00:37:02,483 --> 00:37:10,232 Can the developers at Microsoft force the developers at JetBrain to respond to them? 301 00:37:10,232 --> 00:37:13,757 Yeh, Big time! 302 00:37:13,757 --> 00:37:17,791 Now, think about that in your application's point of view. 303 00:37:17,791 --> 00:37:25,851 Which parts of your application do you want to be protected from other parts? 304 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? 305 00:37:34,771 --> 00:37:38,838 And the answer to the ought to be very very clear. 306 00:37:38,838 --> 00:37:45,152 You would like to protect your business rules from changes to the web. 307 00:37:45,152 --> 00:37:49,706 You don't wanna protect the web from changes to the business rules. 308 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. 309 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. 310 00:38:07,680 --> 00:38:11,912 Which leads us to the database. 311 00:38:14,882 --> 00:38:18,116 What about the database? 312 00:38:20,396 --> 00:38:22,991 Is that your view of the database? 313 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? 314 00:38:31,846 --> 00:38:37,573 Does anybody have a job function of DBA? Do we have DBAs in the room? 315 00:38:37,573 --> 00:38:39,368 Aha I'm safe. Good. 316 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. 317 00:38:49,066 --> 00:38:52,413 Is this how you think about the database? 318 00:38:52,540 --> 00:38:55,061 Because here's my point. 319 00:38:55,135 --> 00:38:57,389 The Database is a detail! 320 00:38:57,389 --> 00:39:00,753 It's not architecturally significant! 321 00:39:00,885 --> 00:39:05,017 The database is a bucket of bits! 322 00:39:05,876 --> 00:39:10,112 It is not an architecturally significant element of you system. 323 00:39:10,112 --> 00:39:12,791 It has nothing to do with business rules. 324 00:39:12,791 --> 00:39:17,263 God help you if you are putting business rules in the stored procedure. 325 00:39:17,263 --> 00:39:25,818 What goes in the stored procedure are enhanced queries, validations, integrity checks, but not business rules. 326 00:39:29,898 --> 00:39:32,519 Why do we have databases? 327 00:39:34,219 --> 00:39:40,744 Where did this whole database thing come from? Why is there Oracle? 328 00:39:45,614 --> 00:39:48,768 Where did we store all that data? 329 00:39:48,768 --> 00:39:53,494 We stored it on spinning disks. Is anybody written a disk driver? 330 00:39:53,494 --> 00:39:58,375 Anybody written a software that controls memory in and out of spinning disk? 331 00:39:58,456 --> 00:40:06,569 Nobody! Oh gosh. Oh... Yeah! disk driver! 332 00:40:06,569 --> 00:40:10,454 What? Diskette? That's good enough! 333 00:40:10,454 --> 00:40:15,290 So getting data in and off of a disk is hard. Why is it hard? 334 00:40:15,290 --> 00:40:18,183 Because of the way the data is organized on the disk. 335 00:40:18,261 --> 00:40:21,820 The way the data is organized on the disk in the circular tracks. 336 00:40:21,820 --> 00:40:26,055 The circular tracks go around the surface of the platter. There can be many platters. 337 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. 338 00:40:35,066 --> 00:40:38,941 Then the disk spins around and you've got to read the data off the disk. 339 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. 340 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. 341 00:40:52,282 --> 00:40:57,368 And then you go into that sector and find the byte you want. 342 00:40:57,368 --> 00:41:01,134 That's a pain. And it's slow. 343 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! 344 00:41:05,141 --> 00:41:13,866 So we wrote the systems that optimize for that particular problem. We called them databases. 345 00:41:15,106 --> 00:41:17,502 But somethings happened. 346 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. 347 00:41:28,339 --> 00:41:30,936 Is anybody have disk in the room? 348 00:41:30,936 --> 00:41:34,012 Is there a spinning disk in this room? 349 00:41:34,012 --> 00:41:37,070 Oh my god, really? 350 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. 351 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. 352 00:41:51,019 --> 00:41:55,998 You watch over next few years. spinning disks begin to disappear. Everything gets replaced with RAM. 353 00:41:56,081 --> 00:41:59,719 And I said RAM, didn't I? 354 00:41:59,719 --> 00:42:04,421 RAM is directly addressable at a byte level. 355 00:42:04,498 --> 00:42:13,672 What we are approaching is a virtually infinite amount of directly addressable RAM that is persistent. 356 00:42:13,672 --> 00:42:17,634 That's where we are going to be storing our data. 357 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? 358 00:42:27,902 --> 00:42:32,101 SQL's pain. Tables are a pain. 359 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? 360 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? 361 00:42:44,662 --> 00:42:49,298 What if we just left it in that format that we want to use it? 362 00:42:49,298 --> 00:42:52,746 If I were Oracle I would be scared to death. 363 00:42:52,801 --> 00:42:57,280 Because the reason for my existence is disappearing out from underneath. 364 00:42:57,280 --> 00:43:02,567 The notion of a big database system is beginning to go away. 365 00:43:05,317 --> 00:43:10,279 How can I protect my application from this detail? 366 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. 367 00:43:19,105 --> 00:43:23,129 I draw another one of those nice big heavy black lines. 368 00:43:23,198 --> 00:43:30,444 And I make sure all the dependencies cross that line going inward towards the applications. 369 00:43:30,444 --> 00:43:35,554 I make the database a plug-in to the application. 370 00:43:35,554 --> 00:43:38,924 So that I can swap out Oracle with MySQL 371 00:43:38,924 --> 00:43:42,706 or I can yank out MySQL and put in CouchDB 372 00:43:42,706 --> 00:43:47,465 or I can take out CouchDB and put in Datomic or whatever I wish. 373 00:43:47,465 --> 00:43:50,248 I can plug in the database. 374 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. 375 00:43:57,116 --> 00:44:01,082 How do we do it? Well, fairly straight forward, there's another interface up there. 376 00:44:01,082 --> 00:44:03,062 I called it here the Entity Gateway. 377 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. 378 00:44:10,159 --> 00:44:14,247 Anything you might query, there's function for, method for 379 00:44:14,247 --> 00:44:19,247 You implement that method down in the entity gateway implementation below the line. 380 00:44:19,247 --> 00:44:23,128 And that implementation uses the database whatever it is. 381 00:44:23,128 --> 00:44:29,917 Notice that no part of the database manages the leak into the application. 382 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. 383 00:44:39,838 --> 00:44:44,115 The implementation of entity gateway will gather the data together. 384 00:44:44,115 --> 00:44:47,673 Create entity objects and then pass them across the line. 385 00:44:47,673 --> 00:44:53,114 So once you get them above the line, they are real entity objects. 386 00:44:55,164 --> 00:45:00,283 Guys using something like Hibernate? Some ORM tool? 387 00:45:00,283 --> 00:45:02,045 Who's using something like that? 388 00:45:02,066 --> 00:45:06,983 Where would that be in this diagram? 389 00:45:06,983 --> 00:45:10,485 In the implementation! Below the line! 390 00:45:10,485 --> 00:45:16,176 No part of that ORM tool would be known above the line. 391 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. 392 00:45:21,664 --> 00:45:25,465 You dont' want your business objects to know that there are built by Hibernate. 393 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. 394 00:45:31,831 --> 00:45:36,131 Keep your business objects pure. Why? 395 00:45:37,741 --> 00:45:40,556 What's an object? 396 00:45:43,106 --> 00:45:45,360 I've got time for this. 397 00:45:46,610 --> 00:45:54,363 What's an object? An object is a set of public methods 398 00:45:54,363 --> 00:46:00,727 And well you are not allowed to know the rest, are you? 399 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? 400 00:46:04,792 --> 00:46:11,459 From you point of view, object is bunch of methods. Not a bunch of data. 401 00:46:11,459 --> 00:46:13,618 And object is a bunch of methods. 402 00:46:13,618 --> 00:46:17,075 An object is about behavior. 403 00:46:17,075 --> 00:46:20,863 An object is about business rules. 404 00:46:20,863 --> 00:46:23,213 It is not about data. 405 00:46:23,213 --> 00:46:26,228 We presume there's data in there somewhere, but we don't know where. 406 00:46:26,228 --> 00:46:29,990 And we don't know what formats in it. We don't want to know. 407 00:46:29,990 --> 00:46:32,973 What is a data structure? 408 00:46:32,973 --> 00:46:40,606 A data structure is a grouping of well known data elements. Public. Visible to everybody. 409 00:46:40,606 --> 00:46:42,761 And there's no methods in them. 410 00:46:42,761 --> 00:46:44,779 Data structures don't have functions. 411 00:46:44,779 --> 00:46:47,263 These two things are exact opposite of each other. 412 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. 413 00:46:54,612 --> 00:46:56,112 Precisely the opposite. 414 00:46:56,112 --> 00:47:00,133 There's no such thing as an ORM. 415 00:47:00,175 --> 00:47:03,339 Object relational mapper? Can't do it. 416 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. 417 00:47:10,268 --> 00:47:12,452 Cause they are completely different things. 418 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. 419 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. 420 00:47:26,615 --> 00:47:31,151 Those entities are not constructed by Hibernate. 421 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. 422 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. 423 00:47:45,239 --> 00:47:48,358 Stuff below the line can be polluted. 424 00:47:48,358 --> 00:47:54,559 Above the black line, those are my family jewels. I'm gonna keep them protected. 425 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. 426 00:48:02,572 --> 00:48:09,793 Frameworks. We like our frameworks. We think they're cool. 427 00:48:09,793 --> 00:48:14,859 We think frameworks save us a lot of time and they do. 428 00:48:14,859 --> 00:48:21,820 But the authors of frameworks entice us to bind to them. 429 00:48:21,820 --> 00:48:26,278 They offer us base classes for us to inherit from. 430 00:48:26,278 --> 00:48:32,477 When you inherit from a base class, you marry that class. 431 00:48:32,477 --> 00:48:40,045 You bind yourself strongly to that base class. There's no relationship stronger than inheritance. 432 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. 433 00:48:47,493 --> 00:48:52,156 But they, on the other hand, are not making any kind of commitment to you. 434 00:48:52,156 --> 00:48:54,684 So it's an asymmetrical relationship. 435 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. 436 00:49:02,305 --> 00:49:06,524 I leave you to make that comparison to yourself. 437 00:49:06,524 --> 00:49:12,336 A wise architect does not make that binding. 438 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. 439 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. 440 00:49:25,605 --> 00:49:30,985 I think I'm gonna put boundaries between my business rules and that frameworks. 441 00:49:30,985 --> 00:49:39,477 So that my business rules are not forever tied to Hibernate or Spring. God know what. 442 00:49:39,477 --> 00:49:43,966 I'll use the framework. And I'll use the framework carefully. 443 00:49:43,966 --> 00:49:49,822 Because the author of the framework does not have my best interest at heart. 444 00:49:55,672 --> 00:50:03,334 Long ago, my son and I and several other people wrote a tool called Fitnesse. 445 00:50:03,334 --> 00:50:06,533 Is anybody use Fitnesse? Oh bunch of you, good. 446 00:50:06,533 --> 00:50:13,149 Fitnesse is a tool for writing customer acceptance test. 447 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. 448 00:50:17,576 --> 00:50:19,397 Who invented Wiki? 449 00:50:19,437 --> 00:50:22,483 Ward Cunningham. Who's Ward Cunningham? 450 00:50:22,483 --> 00:50:26,765 Guy invented Wiki. Ah~ He's a lot more than that. 451 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. 452 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. 453 00:50:40,028 --> 00:50:42,006 And we review him from on high. 454 00:50:42,006 --> 00:50:46,424 He was the guy made phone call to Eric Gamma 455 00:50:46,424 --> 00:50:49,760 Said "You know Eric, you gotta write a book called design patterns." 456 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. 457 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!" 458 00:51:06,937 --> 00:51:12,160 Fitnesse is based on two inventions of Ward, the Wiki and Fit. 459 00:51:12,204 --> 00:51:16,212 I'm not going to describe Fit. I'll describe Wiki however. 460 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. 461 00:51:24,896 --> 00:51:27,807 We knew we wanted make a Wiki. 462 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?" 463 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. 464 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. 465 00:51:50,880 --> 00:51:53,550 "You know we don't really have to do that. Right yet" 466 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" 467 00:51:58,793 --> 00:52:03,312 And that problem was translating Wiki text to HTML. That's what Wiki does. 468 00:52:03,382 --> 00:52:07,185 Takes the funny text you typed into the Wiki and turns it into HTML. 469 00:52:07,251 --> 00:52:10,156 And there was a lot of that translation that we needed to do. 470 00:52:10,156 --> 00:52:14,258 So about 3 month we just forgot about the database altogether. 471 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. 472 00:52:21,414 --> 00:52:22,968 You can see it here. 473 00:52:22,968 --> 00:52:29,995 We created an abstract class named WikiPage and we implemented it with something called MockWikiPage. 474 00:52:29,995 --> 00:52:37,446 The methods of WikiPage had database like funtions such as Load and Save. 475 00:52:37,490 --> 00:52:40,028 But they were unimplemented. The didn't do anything. 476 00:52:40,028 --> 00:52:43,364 And for about three months we worked that way. 477 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." 478 00:52:49,177 --> 00:52:52,039 "Cause now we need to actually store these pages somewhere" 479 00:52:52,070 --> 00:52:54,670 And somebody said "Well, we don't need to do that yet." 480 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." 481 00:53:00,056 --> 00:53:02,590 "I mean we don't really need to store them on disk yet, do we?" 482 00:53:02,590 --> 00:53:06,356 The answer to that was no. Cause all we were doing was writing unit test anyway. 483 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. 484 00:53:14,871 --> 00:53:17,436 And we continued to work for a year. 485 00:53:17,786 --> 00:53:21,611 Continuing to write more and more Fitnesse keeping all the data in memory. 486 00:53:21,611 --> 00:53:24,294 We actually got all of Fitnesse working. 487 00:53:24,744 --> 00:53:27,280 Without ever putting it into a disk. 488 00:53:27,332 --> 00:53:32,169 And it was very cool because all the test went really fast. No database. 489 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. 490 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." 491 00:53:44,721 --> 00:53:46,664 And Michael Feathers was there at that time. 492 00:53:46,664 --> 00:53:50,274 And Michael said "Well you don't really have to fire up MySQL yet." 493 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." 494 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. 495 00:54:06,860 --> 00:54:11,112 And for another 3 months we continued to develop more and more about Fitnesse. 496 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. 497 00:54:16,426 --> 00:54:18,278 Started work like real Wiki. 498 00:54:18,551 --> 00:54:27,959 About 3 months after that we said "We don't need that database" 499 00:54:28,539 --> 00:54:31,807 "It's working fine! Flat files are fast enough." 500 00:54:31,879 --> 00:54:33,691 "Works okay, that way." 501 00:54:33,732 --> 00:54:38,884 We took that highly significant architectural decision and pushed it off to the end of planet. 502 00:54:38,884 --> 00:54:43,799 We never put that database in. That's not quite true actually. Somebody else did. 503 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." 504 00:54:49,745 --> 00:54:52,371 We said "But why? It's working fine in the flat file" 505 00:54:52,495 --> 00:54:59,032 He said "Corporate policy, all corporate assets must be in a database." 506 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. 507 00:55:04,415 --> 00:55:11,854 So, we said "Well Look. If you really needed it in a database." 508 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." 509 00:55:24,251 --> 00:55:27,162 And he came back a day latter and the whole thing running MySQL. 510 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. 511 00:55:32,018 --> 00:55:37,936 Here's an architectural decision that we deferred and deferred and delayed and delayed. 512 00:55:38,003 --> 00:55:41,034 We delayed right up to the end of project. Ne never did it. 513 00:55:41,034 --> 00:55:45,352 Something that we thought we had to do it first, we never did it. 514 00:55:45,352 --> 00:55:49,120 That leads to the final principle. 515 00:55:50,619 --> 00:56:00,209 A good architecture is an architecture that allows major decisions to be delayed! Deferred! 516 00:56:00,209 --> 00:56:05,107 The goal of an architect is to not make decisions. 517 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. 518 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. 519 00:56:21,953 --> 00:56:28,929 Don't tell me that the architecture of your application is a bunch of frameworks. 520 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.. " 521 00:56:35,568 --> 00:56:37,347 You're not telling me anything. 522 00:56:37,347 --> 00:56:40,744 You're telling me the tools. 523 00:56:40,744 --> 00:56:43,011 That's not the architecture of your application. 524 00:56:43,075 --> 00:56:46,104 The architecture of your applications are the usecases. 525 00:56:46,104 --> 00:56:50,460 And you want your usecases to not know about those tools. 526 00:56:50,460 --> 00:56:54,847 You wanna be able to defer the use of those tools for as long as possible. 527 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. 528 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. 529 00:57:07,483 --> 00:57:12,177 Just so that you can see some pages without firing up some gigantic framework. 530 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. 531 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. 532 00:57:25,347 --> 00:57:34,497 Next time you have a application to write, think about what you can delay. 533 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. 534 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. 535 00:57:55,076 --> 00:57:57,959 Which are the real core of your application. 536 00:57:59,809 --> 00:58:03,990 Now of course, customers are gonna wanna see web pages. 537 00:58:03,990 --> 00:58:10,463 Okay, you can stil make a plug-in architecture and show them web pages running. 538 00:58:10,514 --> 00:58:13,339 You don't have to make a lot of commitments to the frameworks. 539 00:58:13,339 --> 00:58:16,647 You don't have to make a lot of commitments to the web framework. 540 00:58:16,647 --> 00:58:19,084 You can probably put something simple up it first. 541 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. 542 00:58:25,807 --> 00:58:29,285 So that at a moment's notice you can unplug it and plug something else in. 543 00:58:31,245 --> 00:58:35,177 And that probably brings to me the end of my talk. 544 00:58:35,857 --> 00:58:39,417 I already talked about that earlier. (TDD) 545 00:58:41,737 --> 00:58:45,463 So thank you all very much. are there any questions? 546 00:58:47,635 --> 00:58:50,950 Very difficult to see, so I'm gonna come down here. 547 00:58:54,550 --> 00:58:56,664 Oh that doesn't help at all. 548 00:58:57,464 --> 00:59:01,372 Okay, anybody have any questions? 549 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. 550 00:59:04,449 --> 00:59:05,236 Yep. 551 00:59:05,236 --> 00:59:11,963 (Someone is asking a question) 552 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? 553 00:59:21,151 --> 00:59:24,337 What an interesting question! 554 00:59:24,337 --> 00:59:30,947 It could be nothing more than RAM. Why do you need anything to replace them? 555 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? 556 00:59:36,562 --> 00:59:38,857 Oh but let's say you need something. 557 00:59:38,857 --> 00:59:41,488 Okay what might it look like? 558 00:59:42,458 --> 00:59:45,557 Well, who's heard of the CQRS? 559 00:59:46,437 --> 00:59:47,719 Oh yeah, few of you. 560 00:59:47,719 --> 00:59:49,933 CQRS, what an interesting idea? 561 00:59:49,957 --> 00:59:54,999 If we have infinite amount of high speed memory. High speed RAM. 562 00:59:54,999 --> 00:59:58,390 Or maybe it's even disk but who cares. 563 00:59:58,390 --> 01:00:02,369 Why would we store the state of anything. 564 01:00:02,369 --> 01:00:05,195 Why wouldn't we simply store the transactions? 565 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. 566 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. 567 01:00:19,295 --> 01:00:23,381 Why wouldn't we store the transactions and reconstruct the state. 568 01:00:23,381 --> 01:00:25,870 And you say to yourself "Well it will take a lot of time" 569 01:00:25,870 --> 01:00:28,512 Yeah, but we've lots of processing power. 570 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. 571 01:00:40,331 --> 01:00:44,299 Why wouldn't we store just the events? 572 01:00:44,299 --> 01:00:46,264 And I think that's an interesting idea. 573 01:00:46,296 --> 01:00:53,412 If we store just events, then we would never delete anything. 574 01:00:53,412 --> 01:00:55,640 We would never update anything. 575 01:00:55,709 --> 01:00:59,436 You know CRUD? Create. Read. Update. Delete? 576 01:00:59,436 --> 01:01:04,702 We'd loose the last 2 letters there. All our applications would be CR. 577 01:01:04,702 --> 01:01:08,752 Create and Read. We would never update. We would never delete. 578 01:01:08,752 --> 01:01:13,568 And when you don't update and you don't delete you don't need transactions. 579 01:01:13,568 --> 01:01:17,292 There can't be any concurrent update problems if you're not updating. 580 01:01:17,292 --> 01:01:20,151 That's interesting! 581 01:01:20,151 --> 01:01:25,436 Are there frameworks out there that allow you to do things like that? There are. 582 01:01:25,468 --> 01:01:27,139 There are number of them out there. 583 01:01:27,139 --> 01:01:31,633 That are write only databases. Write once and read many times. 584 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. 585 01:01:35,381 --> 01:01:37,632 But you can go out there and look for them. There are out there. 586 01:01:37,632 --> 01:01:40,162 You might replace them something like that. 587 01:01:40,162 --> 01:01:45,731 You might replace them with Couch or Mongo. Or you might create some other thing. 588 01:01:45,778 --> 01:01:51,519 It really doesn't matter. You don't have to have some massive vendor offering. 589 01:01:51,583 --> 01:01:53,852 From some gigantic company in the sky. 590 01:01:53,852 --> 01:01:58,568 That blesses you and says "Yes son, you may use my database system." 591 01:02:00,218 --> 01:02:02,967 Maybe you can just make your own. Not that hard. 592 01:02:02,967 --> 01:02:04,775 Anybody else? 593 01:02:07,625 --> 01:02:09,379 Yeah, that actually helps a lot. 594 01:02:09,379 --> 01:02:12,216 Okay, anybody else with questions? 595 01:02:15,066 --> 01:02:27,373 (Someone is asking a question) 596 01:02:27,373 --> 01:02:31,933 Differing decisions does not work very well when.. 597 01:02:33,923 --> 01:02:42,383 When you have a family? (People laughing) 598 01:02:43,633 --> 01:02:47,074 You mean in general. There are decisions you can differ. 599 01:02:47,074 --> 01:02:49,872 For example, what language we gonna write this thing in? 600 01:02:49,872 --> 01:02:52,603 You gonna have to make that decision pretty early. 601 01:02:52,603 --> 01:02:56,085 Right? Cause you know you gotta write some. 602 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. 603 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. 604 01:03:06,887 --> 01:03:09,262 You have to commit to framework. No. 605 01:03:09,752 --> 01:03:13,585 A family vacation that's what you were saying here. 606 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? 607 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? 608 01:03:31,206 --> 01:03:36,086 Maybe our car break down in the middle. Or before we go on the vacation. 609 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. 610 01:03:43,321 --> 01:03:44,936 We can still go on the vacation. 611 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. 612 01:03:55,893 --> 01:03:59,233 That one can be differed to the last minute. 613 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. 614 01:04:04,031 --> 01:04:05,521 And why would you do that? 615 01:04:05,561 --> 01:04:09,075 You might have gotten a race. You might have more money. 616 01:04:09,075 --> 01:04:12,391 You might have a baby. Need more space. 617 01:04:12,441 --> 01:04:17,674 A lot of reason you might wanna buy that car at the last minute. 618 01:04:18,904 --> 01:04:20,818 Anybody else? 619 01:04:21,862 --> 01:04:24,136 Yeah, way back there. 620 01:04:24,136 --> 01:04:29,320 (Someone is asking question) 621 01:04:29,320 --> 01:04:31,535 How do you deal with legacy architecture? 622 01:04:31,535 --> 01:04:34,765 Okay, that's gonna take me more than a minute. 623 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. 624 01:04:40,261 --> 01:04:41,959 Incrementalism. 625 01:04:42,249 --> 01:04:48,166 Everybody faced with legacy code wants to throw it away and write it over. 626 01:04:48,198 --> 01:04:50,189 Please don't do this. 627 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. 628 01:04:56,185 --> 01:04:58,463 Take little bits of it. 629 01:04:58,463 --> 01:05:01,495 And rewrite those tiny little bits one at a time. 630 01:05:01,495 --> 01:05:04,145 And get them working one little bit at a time. 631 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. 632 01:05:08,029 --> 01:05:12,065 And then start over and start re-implementing the patch work. 633 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. 634 01:05:17,045 --> 01:05:20,421 You wanna do that while you also adding new features. 635 01:05:20,421 --> 01:05:23,928 In fact, that's just generally cleaning your code. 636 01:05:23,928 --> 01:05:27,915 Please don't try the big re-design. You'll get hurt. 637 01:05:28,022 --> 01:05:32,956 Thank you all for your attention. I'll see you another time.