 Video equipment rental costs paid for by peep code screencasts. Hi, I'm Glenn Vanderberg. I'm here to talk about tactical design and this really isn't much of a ruby talk. It's informed by my experiences with Ruby and work with projects recently, or the past two or three years, but I presented it and got accepted and I hope you'll find it interesting. Before I really get into it, I want to address an omission. I really enjoyed Evan's keynote last night, but my friend Chris Morris and I were standing at the back of the room talking and we realized, and Chris in particular noticed that Evan had kind of missed a very important Ruby community meme that it's really important and in some ways it's a signature Ruby community meme. Evan, you alluded to it, but sort of obliquely, subtly, but you didn't actually mention it. It was an extension of Evan's keynote here, cussing on slides. So that said, we'll see if that keeps going strong or fades away. Tactical design, raise your hand if you design software. I gave a trial version of this talk on Tuesday night at Dallas Review Brigade and I asked that question and a couple of people didn't raise their hands and I said raise your hand if you're a programmer and then they raised their hands and said, if you're a programmer, you design software. Now, okay, raise your hand if you're ever in a position of teaching design to other programmers via mentoring. Okay, pretty much everybody. So I'm targeting the right audience. Design is hard and in my experience teaching design is even harder. And part of that comes from the fact that there are aspects of good design that we don't understand. We might, in our gut, sort of know it when we see it. My boss, Stu Holloway, actually shows a picture of that Supreme Court judge that said, you know, I don't know what obscenity is. I can't define obscenity, but I know it when I see it. And sometimes that's what good design is and when you can't really articulate what it is. It's hard to teach. But I think there's more to it than that. Over the past few decades, we've learned a lot about what constitutes good design and we have learned how to articulate it. But sometimes it's just really hard to teach it to younger programmers or less experienced programmers. And I've thought a lot about why that is. One of my favorite books in the software field is the Mythical Man Month by Fred Brooks. It was published a long time ago. 22 years ago, he wrote an essay called No Silver Bullet. And in that essay, he wrote this, we can get good designs by following good practices instead of poor ones. Good practices can be taught. And I read that and I have to say, I read it fairly recently, I have to say, I thought, you know, in my experience, that's just not true. But then he went on and clarified things a little bit. Whereas the difference between poor conceptual designs and good ones may lie in the soundness of design method. The difference between good designs and great ones surely does not. Great designs come from great designers. Okay. Well, Brooks sort of from that point goes on to despair about teaching design and says, well, what you ought to do is just find and cultivate great designers. And I can't disagree with that. But at the same time, we need more merely good designers. And we need more merely good designs. If 10% of software systems out there in industry were elevated from their current state to simply good design, not great, we'd all be a lot better off, right? So here's the obligatory programmer productivity graph. And I've been talking about design skill and this graph is about productivity. But I really think when we draw this graph, we're talking about that y-axis over there is labeled as sort of the measurable second order effect of a less measurable primary thing, which is just skills. And so I'm willing to posit that this graph applies to design skill as well. So if that's the way the world is and there are a few programmers with great design skills and a large number of programmers with very weak design skills, what do we do to improve our field? Well, we can cater to the average programmer and we kind of tried that for 10 years or so recently. And that doesn't really seem to have worked very well. Building tools and platforms that cater to the average doesn't seem to yield very good results. We can take the Rails approach of catering to the natural designers and I like that approach and it's a lot better, but it's not optimal. Well, doing just that isn't optimal. There aren't enough natural great software designers to do all that needs to be done. And so they still get stuck cleaning up the messes from the others. And that's lucrative and it gives us the knowledge that we're not going to be out of work anytime soon, but cleaning up those messes isn't very satisfying. So third option is to just scare off the really bad ones and that's fine with me, but it still doesn't really solve the problem. We can identify and cultivate great designers, but we need more great designers and more merely good designers. And I've been really thinking a lot as I work with programmers, as I pair with developers, at our customers. How do you best teach, mentor, uplift, and improve other people's skills with respect to design? So let's go back to this graph again to give some clarity to what I'm talking about. I think we can kind of divide this graph into three parts. Over on the left is natural designers. And those are the people that are interested and care and probably have some natural aptitude. And one way or the other, they are going to figure out how to do it right. Somebody yesterday, I think it was Rain in his talk, was talking about how he just worked and studied and tried things and figured out how to do software design. And I know a lot of people like that and there are all kinds of different strategies, but they all seem to have just figured it out on their own or figured out how to get the help they need. And over on the right, I think, and we can argue about exactly where to draw the line, but over on the right, I think we can agree that there's a large number of people who, as far as learning good design skills, are basically hopeless. But right there at the knee of the curve, I think is a group of people that could learn it if they were taught the right way. Or maybe not be great, but at least be better. And I've been very frustrated with the traditional ways we've tried to teach those things. But that's kind of the goal of this talk. That's what I'm thinking about. How do we get better at improving people who are potentially good software developers and designers and help them learn to think about design qualities in their code? And I really, you know, I liked hearing Matthew's talk about his work in Tanzania and teaching people by pairing. I think that's the only way that stands any chance is working with people directly and mentoring them side by side. It's the only way I've had any success. But even then, I've been frustrated trying to teach a pair design principles and it just doesn't seem to sink in. So I started trying some different things. Let's quickly look at sort of how we've come to understand design principles. There's been a lot of work on this over the years. The first thing was 1979, structured design by Jordan and Constantine. Recently, in his keynote address at RailsConf, Kent Beck referred to this as sort of the laws of physics of software development. And in this book, they introduced the concepts of coupling, cohesion, factoring of code, and encapsulation. And I'm kind of willing to go along with that. That's sort of the fundamental laws of software design. But that was 30 years ago and just introducing those terms doesn't seem to have helped very much. Bertrand Meyer in 88 introduced design by contract and a stronger notion of encapsulation. And he informally introduced the notion of responsibility. And he also introduced the open-closed principle which still is pretty strongly taught today. 1990, Wolfsbrock introduced responsibility driven design, picked up what Meyer had been talking about and made it stronger and built a whole design method around it. And then in 94 there was design patterns, of course, which isn't really so much design principles as a canned set of solutions that sort of embody those principles for particular situations. So you can think of it as design by example. And I think this book grew out of the same kind of frustration with the big principled approaches to software design that I've been feeling. Well, it's not working teaching the principles, we're going to have to just show them what it looks like, except I don't happen to think that worked particularly well either. More recently is a book by Bob Martin, Principles of OO Design that tries to sort of correlate and gather a bunch of principles defined by several different people over the years and put them together on a sound footing. And I'll talk more about this a little bit later. Eric Evans' domain-driven design advises focusing on your domain model and turning that into a system of names and terms that you and your customers and the subject matter experts can agree on and communicate with and most of the rest of your design comes fairly naturally from that. And I think there's a lot of wisdom in that approach. And I think all those things are great books, but I haven't had much luck using them to teach people that aren't natural designers in their makeup how design works. And to examine why, let's look at Bob Martin's principles. These are the five principles of OO design that he espouses in his book. The single responsibility principle that every class should do one clear and well-defined thing and everything in that class should have to do with that task. The open-close principle that classes should be open to extension but closed to modification. The Liskov substitution principle which deals with what kinds of extensions are allowable to make when you're inheriting and creating subclasses. The dependency inversion principle which is about breaking dependencies between layers by introducing interfaces. And the interface segregation principle which deals with how you allocate responsibility and methods to individual interfaces. Part of the problem with this and with all the other approaches I've described is that there's an embarrassment of riches. These are sort of high-level, flighty principles and there are a lot of them and you have to remember them all while you're in the middle of coding and juggling the requirements of your application and different terminology and making the language fit the problem and keeping a lot of state and variables and things juggling in your head. And the other part of the problem I think is that all of these principles when they're applied to object oriented programming deal primarily with classes. They deal with division of the task among classes and their relationships and how you use inheritance versus composition and the difference between aggregation and association and how far you can go in certain directions. They're all about classes. And what I've noticed is that average and even a lot of above average programmers have trouble thinking while they're working on code at the level of classes. They work with blinders on. I'm working on this method in the middle of this class and actually be quiet about that because right now I'm working on this for loop and you're not thinking about the big picture. So if that's the case how can we teach them design? Years ago on Ward's Wiki, the original Wiki Web, Ralph Johnson wrote something that has always stuck with me. It's one of my favorite quotes about software. With the right value system making good short term decisions leads to good long term results. I think that that's the purpose of a value system. We need to figure out the way to live so that when we are in the middle of life we do the right thing. When our neighbor comes over to argue with us we're not going to start thinking about how this will affect our life ten years from now but we react according to the way we were taught and the way we taught ourselves. Which is a long winded way I guess of saying think globally act locally. But I think this is right and putting aside for a moment moral issues with regard to value systems and looking at it purely from a pragmatic point of view I think that is what we use value systems for. Just to take a simple cliched example honesty is the best policy. Well when you think about the effects on people and relationships and everything else it's easy to construct contrived examples that sometimes do happen in the real world where being honest will result in a worse outcome. But more often than not vastly more often than not being honest keeps things simple and results in the right outcome and works out better than the alternative and so that becomes a value we live by so that we don't have to every time we open our mouths think about the larger consequences which are more difficult to think about. We just say okay it's better to always be honest because that has the best practical consequence most of the time. So when I talk about tactical design what I mean is choosing the right value system that works while we are in the middle of coding rather than the laws of physics of software development Maxwell's equations and what have you we want what engineers use as rules of thumb simplified formulas that might not work in outer space at eight tenths of the speed of light but they're fine for right here and give the right results most of the time. Talking about designing at the level of methods and lines of code and again let's be clear about my goals. I don't think this is necessarily the way to achieve great designs but I think this is a way for people without the design skills already to achieve decent good designs that are better than what they would achieve otherwise. The question of course is which values and we could have arguments about this and I kind of hope we will. I think it would be nice to have a lot of dialogue about design principles that apply at this scale but naturally I have a proposal and the proposal is to start with two coding rules more or less coding standards short methods and few methods per class I think we can all agree on that and in a team or even with your pair partner just agree that you're going to set some arbitrary and rarely to be broken limit on these things and then add three principles to that. The first one I'm going to call you know the single responsibility principle sounds a bit theoretical and rough so let's just call it do one thing. The second one Dave over there has already given us a nice friendly acronym for dry. Don't repeat yourself and finally one that I call the uniform level of abstraction and if anybody has a nice handy friendlier name for that I'm open to suggestions. A few nights ago Greg Vaughn suggested spare me the details which comes close to what I'm talking about but not quite. So do one thing. This was first articulated by Tom DeMarco in structured analysis and system specification. Every object should have a single responsibility and all its services should be narrowly aligned within that responsibility and in my formulation of it I extend that to methods as well. Each method should have one task that it's supposed to do. I think we all know dry. Don't repeat yourself. Every piece of system knowledge should have one authoritative unambiguous representation. Now the way Dave and Andy formulated this principle it referred to more than just code duplication. It was much deeper than that but I think for purposes of tactical design just sticking to code duplication is probably enough. It gets people started and the uniform level of abstraction and the only place I've really seen this laid out is in small talk best practice patterns and Kent calls it the composed method pattern which I don't think is a particularly good name for this and it starts with divide your program into methods that perform one identifiable task that's just do one thing really but the core of uniform level of abstraction is keep all the operations in a method at the same level of abstraction. Your method should be a description of the steps to perform the task and if it starts off with a call to a fairly high level method that has a nice name that describes what that step is you're off to a good start and the reader of the method is going to find it easy to follow that and if the next line is the beginning of a loop that iterates through a data structure and takes some operation on each element of the data structure now the reader has to drop down to a different level of abstraction and follow the iteration and figure out why it's doing that to each one and it's better to refactor that and give that a name that is at the same level of abstraction as everything else in the method. So my claim which I make based on experience pairing with junior programmers recently is that adhering to those three principles results in decent again not great but decent designs but then has more important and longer reaching and farther reaching effects. It forces the developers to discover simple design patterns themselves and it provides them with an appreciation of the forces and principles of design through the process of adhering to these very small fine grained design principles and through that it prepares people to understand the higher level principles and gets them off to a good start. And another thing I like about these two little rules and the three principles are that any competent programmer can understand them while coding a single method and to a large degree they can be reviewed and critiqued with objectivity. Cohesion and coupling and things like that we can get into arguments and even fairly skilled programmers can get into arguments about when you've got it right and how much is too much and things like that but do one thing and dry and uniform level of abstraction they can be evaluated fairly objectively. So do one thing. It's the basic it is a basic principle driven definition of simplicity and by principle driven I'm using that term to contrast it with metric driven. Somebody doesn't have to do a lot of calculations or count lines of code or blocks or anything else to arrive at a notion of whether this is of how complicated or simple a method is. They can look at whether it does one task. This serves as an organizing principle for your code and it provides a reason a rationale for when to split a method up into multiple pieces. When I say it's the organizing principle I mean that other principles and rules that we've defined might cause you to move something or break something up into two pieces and move part of it somewhere else and the next question is okay where do I put it. Or in the case of the dry principle rather than splitting things up and moving it somewhere else you might need to take things from two different places and unify them but still the decision the question remains where does it go and do one thing helps to provide an answer to that and if there isn't a place that has the right responsibility for what you've got it might provide a rationale for creating something new. Dry. I don't think I have to justify this to a Ruby crowd. Evils of duplication are very well documented and we understand all that but outside of communities like this and people who have a good understanding of design even this isn't very widely understood and one of the things that got me started thinking about tactical design was something that Bruce Eccl posted a few years ago actually paraphrasing Scott Myers. He called it the most fundamental concept in computing. He said it's practically ignored and perhaps not even understood by a large percentage of programmers. If we can't even get people to understand and follow the dry principle what hope is there for anything more sophisticated. And I read that and I thought you know that's true. So let's throw out the things that are more sophisticated for a while and focus on that. The obvious benefit of dry is that you eliminate duplication and that's a huge benefit. It gives programmers experience with refactoring. It pushes you to learn about your language capabilities. Depending on what the duplication is and where it is and what kind of thing it is just combining it into one method somewhere might not be enough to eliminate the duplication. I've heard David Heinemeyer Hanson say that trying to follow the dry principle in the evolution of rails helped him to learn about all of the interesting dynamic metaprogramming features of Ruby because he was looking for places for the right place to unify duplication that he found in different parts of his code. And it starts you thinking about the right place. So this meshes very well with do one thing. We've got this here. We've got this here. Where should it go? So it takes a programmer away from the strict practicality of I need it here and I need it here to well we need it both places but it needs to be one place. Where should it go? And that's a design question. And so in that sense it's the gateway to serious thinking about design. Uniform level of abstraction. This one's rather obscure again probably because it doesn't have a catchy name or friendly acronym or something like that. I've had very good experiences using it with junior programmers. And I started using it one day when I was working pairing with a programmer and there was a method that I didn't like and I didn't know up here why I didn't like it. I knew down here and I said we need to split this up. Well why? Well it's too complicated. It's six lines. And one of them is a comment and one's blank. How can it be too complicated? Well I don't know but it just is. And so we argued for a while and he didn't want to break it up and I did and I finally was able to put into words what I didn't like about it. The middle two lines were at a completely different level of abstraction, much lower. And so he bought that. Okay. Now that makes sense. And we moved it and we were able to give that a nice name and now the top level method read like a little recipe. And the interesting thing that happened there was that, well we'll get to that here. Uniform level of abstraction keeps methods easy to read and understand. It makes methods easily refactorable because it keeps them fine grained and breaks the small parts of a larger recipe out into their own methods. So it gives you individual pieces that you can override or extend if necessary rather than having to cut and paste the entire method body and make changes in the middle. It encourages a focus on good method names. When you move that thing out you need to think about what it should be called and fit it into the level of abstraction of the top level method. And it can help expose dry violations. That first day when I use this principle to justify what I wanted to do, as soon as we moved that thing out into its own method we realized that doesn't belong here at all. That wasn't part of my original plan. I just noticed that it was kind of low level compared to everything else but we moved it out and we realized that it was in the wrong place and it belonged in a different class and we moved it there and overall improved. And then once we had done that we realized that other things were doing similar kind of work and could instead use the new method we just created and removed a big dry violation. And again all of this I think should happen under the guidance of somebody more experienced. But the other thing is that nevertheless a programmer working on their own, a junior programmer working on their own can still apply these principles and learn something from them even without a guide. I did and he bought that. I still wish I had a better term in general but in his case he bought that and I've used it since and people tend to understand what I'm talking about. So it's not a bad term but it's not the one I'd like. So as a case study and again I don't think I need to justify these individual principles to this crowd but it is notable and I've had this conversation with David that when he started building Rails he didn't really set out to build a framework I think it was in the back of his mind but he built an application and he had some values. He had fairly strict adherence to dry and he had a reasonable adherence to the uniform level of abstraction and he tried to make his code expressive and that through that evolved Rails. I'm not trying to claim that David didn't apply a deeper understanding of design because he clearly did but these were some of the principles that he followed. And for uniform level of abstraction, how many of you have ever heard the story of Whycash and Advanceers, Ward Cunningham? Jim I expect you've heard this story before or read about it. In the early 90s Ward Cunningham was working on a bond trading system in Smalltalk and there was a complicated method that was causing them some trouble and it was at multiple levels of abstraction and they wanted to refactor it. But it was one of those methods that had a lot of local variables and the local variables are used kind of all over the place and so in order to refactor this method you have to figure out which local variables need to be passed in where and that gets really messy and so to avoid that they used a pattern called method object where you just copy the whole method over to a method in some separate object and you make all those local variables instance variables so that anything in the class anywhere can reference them and then you just start carving it apart and you don't have to worry about that anymore and the sole purpose of this object becomes to post that method and so instead of before where they had this was a bond trading system and the method in question was advance. It was a method on the position class, a position in one particular security that a trader held and they would call position.advance with some input and you get a new position out and so they moved advance over into a method object and so instead they would say newAdvancer with this position and the inputs.invoke and you'd get the new position out so the advance was a method object and some funny things happened and again the initial impetus for this was they wanted this method to be at the same level of abstraction. Method objects are usually temporary constructs in your design. You use them to break a method apart and then once you've broken it apart you start putting the individual places where they go and then eventually you get rid of the method object in the middle but advance didn't work like that. It became a core domain object in their system and they were working in the domain driven design style that Eric Evans recommends and so their subject matter experts knew about their domain model and the subject matter experts started requesting new features in terms of writing a new subclass of advance. They would do this instead of that and they worked that way for a while and then and everybody agreed that it was a core domain object that couldn't really explain why very much and none of them had ever heard of it before. Even bond traders had been working in the field for years but it was a fairly natural way of thinking and then later there was another part of their system they were having trouble with which was tax calculations on trades and that tended to be buggy. There are lots of bugs in the system and recurring bugs related to tax calculations and finally somebody realized and tax calculations were done by position objects and finally somebody realized well all the information we need is kind of ready to hand in the advance or why don't we make the advance or do the tax calculation and they did that and it became much simpler and more robust and they stopped having these nagging bugs related to tax calculations and it was at that point that Ward finally realized what was going on and why the advance was so important because the traders themselves cared mostly about what their positions were but the IRS of course cares mostly about how you came to have them and that is the responsibility that the advance had was wrapping up the knowledge of how a trader came to have a particular position and that's where the tax consequences come into play. So even small fine grained design principles when applied can lead to much larger level of level effects. These are generative principles. They give rise to good results in several ways. Your end up in code is reasonably well designed. It's pretty well factored. It has clear and reduced dependencies. It helps people think more clearly about design and I think by applying these principles for a while those larger principles that we talked about earlier start to make more sense. I see now why high cohesion and low coupling are important. I see now why responsibility is a good idea and again this is not the end point. This is the introduction to good design. A lot of what it's about is what I call awakening the sense of smell. Knowing how to fix a problem in your code is only half the battle and in some ways it's the easier half of the battle because you can stop and think about it and scribble on a white board and try multiple things and go ask somebody more experienced than you and Google for it and evaluate multiple alternatives and there's all kinds of things you can do. Noticing that there is a problem is the other half and I think it's the harder part of the problem especially for less experienced programmers especially because it has to occur while you're in the middle of something else while you're focused on your deadline trying to get this test to pass writing this method trying to keep all that logic in your head and you're focused on other things and so noticing that there is a design problem in your code often has to occur subconsciously or not at all and large-scale abstract principles are hard to think about at that at times like that and smaller scale tactical principles are much easier. One thing I've noticed working in large organizations with with horrible code bases and people who've worked there for many years is you know you wonder why things are the way they are and why these people don't care more and something I realized a couple years ago is that many working programmers have never in their entire career seen clean simple code that does real work. They've seen it they've seen toy code in textbooks and in their programming classes that's clean and simple and they've seen actual valuable code that does real work in their job and it's crap and as a result they don't know that they should be striving for clean simple code in their jobs and somebody might have told them but they don't know in their gut and and I think that these three simple principles and beginning to teach design in terms of small-scale decisions rather than large scale decisions that are harder to understand harder to understand the value of and harder to think about in the minute-to-minute flow of programming can go a long way towards changing that and I'm a little bit under time but that leaves time for questions and observations and things like that. Dave, how do you motivate good design and how do you make people want to do it? Well I think partly I have two answers to that one is I think the the hopeless folks down on the far right right side of that graph just simply aren't going to care and I don't know any way around that but I do know a number of programmers who want to if they can and if they can see the value and see a way they understand. You know I think it was Rain yesterday who was talking about for a while when he was learning design he sat with the book of the the patterns book open and as he was programming sort of every step along the way would look obviously and until he had internalized those things and didn't have to think so hard about them he's one of the ones who cares enough that he's gonna find a way to do it and and out here there are those who just don't care I think in the middle there are people who do care but it just seems too hard. The other answer is that and this is why I think the right way to do this is pair programming or close collaboration. I've seen motivation grow simply by small successes oh that's better and in the process we're refactoring it we found a bug that we might not have found otherwise and after doing it for three weeks I've noticed that adding some of these new features are easier than I expected because the code is written this way and it's you build motivation the same way you do when teaching anything you set them up for small successes early instead of setting them a big unachievable or apparently unachievable goal pretty far out. Does that make sense? Joe did you have a question? Oh okay yes and I discovered early how well a lot of their techniques work and since then basically almost everywhere I go not only do the developers not care they don't want to know and they won't actively resist any implication that there might be a better way of developing the software. Right so the is that is that just an observation is an observation that that you know a lot of places you go people don't care and will actively resist the suggestion that there's any better way of developing the software. I've seen a lot of that too but I wouldn't say it in my experience that it's that high that it's 98% of the developers I've worked with and and I was talking with somebody recently and this is another reason I kind of like this approach when you go into a project that's existing and you take a look at their code and it's awful you if you if you say wow this whole thing is crap and of course I'm drawing sort of extremes here to make an analogy but if you say this whole thing is crap and it really could have been done a lot better there's going to be a lot of resistance to that because what you're basically saying is what you've spent your last six years on is completely worthless but if you're sitting down beside somebody fixing a bug or working on a task and you say well I'm having a hard time understanding this method but maybe it'll be easier if we split it up a little bit and and and work on on a part of the system rather than than attacking the whole I haven't found too much resistance to that that's not I mean that's really just a gateway to the larger problem but I think that's how you start you you start by by finding ways that they won't resist to show them in tiny isolated areas of the system and gradually building that into an understanding of something deeper I've also been in situations where I thought the code base was unsalvageable and I had to say you know that that the whole thing is crap but not always anybody else oh yeah yeah we it's going to take a while to build a culture where programmers collaborate on things and and I think we have to have that to really make much progress right management can certainly and often do set up incentives that discourage programmers from taking care and learning how to do things the right way and you know there are many aspects that need our attention when it regards to when it comes to lifting the level of our profession and our industry and this is just one of them and and getting management to understand the cost of technical debt is another one go yeah it you people who have been established in their career for 20 years are always in general going to be more resistant to learning new things and changing the way they work than young developers straight out of college who know that they you know they're gonna have to learn or most of them do know they have to they have some things to learn before they can be good at their job and so that's kind of one of the reasons I think it's fun to be in the Ruby community because there are a lot of young developers who are just starting out in their career and they're getting off on the right foot and starting their career in a culture that values these things we don't across the whole community we don't have it all right by any stretch of the imagination but there's a lot of value in good software hygiene and source control and unit testing and pair programming and collaboration with your community and peer review and things like that so you know it's sad to say that progress might have to just be slow or isolated until you know certain people retire but that's also the way of the world sometimes but that doesn't mean we shouldn't try mm-hmm we don't get paid for refactoring okay always leave your nest a little cleaner than what was when you arrived and it may be just a little bit I was a few years ago I joined a project and it was it was a Java project and there was a it was it was not it was one of those rear Java projects that was standalone it wasn't running in some big application container or anything but the core method the driver of this whole whole system was like 500 lines long oh sorry so I started but but I knew I wasn't going to understand the project the system until I understood that method and I knew there was no way I could understand it the way it was and they they said I asked if I could refactor it and they said no and so I started refactoring it and I but I didn't I I was going to abide by their rule I wasn't going to check in my refactoring but I had my defense all lined up is like this is the only way I can understand this code I'm going to refactor it and then just keep the refactoring around for reference but but I've got to refactor it to see how it works but then what I hoped would happen and was almost certain would happen did which was after about three hours I got down to where almost everything was pulled out into little small methods and I had about a 40 line main method now and all of a sudden the bugs started to become obvious and I mean so obvious you couldn't miss them with a blindfold on and it simplify more and there's a bug here and there's a bug here and there's a bug here and a couple of them I don't remember the details but a couple of them were things that were like time sensitive or sensitive to you know tiny details of formatting of the input data or the actual values of the input data which never would have been caught by testing but certainly would have actually been triggered in the wild and somehow I got permission to check my refactored version in I'm not I I tried I tried to to make sure I put the word you know in in some cases or something like that in that statement I by no means characterize all veteran programmers this way I'm talking about you know that I'm actually talking about the weak programmers with weak skills no matter what their age there are are weak programmers with weak skills and and I know I'm this way too about things that I've been doing for a long time now that I'm in my mid 40s I'm much less willing to listen to criticism about the way I am and and that I need to change then I was 20 years ago and and so yeah I'm not saying that all veteran programmers have weak skills and we're just gonna have to wait for them to retire what I am saying is that people by their nature do get set in their ways and when they've been doing something a certain way for a number of years and they've learned to be comfortable doing that and they haven't gotten fired yet it's often difficult to get through to them and show them the value of doing something a different way and people who are fresh out of school tend to and again there are exceptions to that rule as well but they tend to know that they've got a lot to learn and are a little bit more malleable yes right I agree with you a hundred percent and thanks for forcing me to clarify myself somebody over here oh I'm so glad you brought that up because the story I told about asking permission to refactor that big method was over eight years ago and I would not ask today I am my customers are paying me to be a professional software developer and that implies professionalism and writing tests and refactoring is a part of my job and I think it's Bob Martin who says you know he doesn't expect his doctor to take his advice about how to do the surgery because his doctor is a professional with special skills and he knows what is the responsible way to do this thing and which shortcuts you can't take and it is a part of my job to write tests and refactor and clean up code and leave it nicer than I found it and I don't ask permission for those things anymore you're right thanks mm-hmm right yes yeah the difference in mindset between craftsmen versus factory worker is important and again not not everybody who enters this field cares enough to ever want to become a craftsman but I think there's I think within the set of people who can do that there's a division there's the people who sort of whether whether because they care so much or have the natural aptitude or whatever are going to figure it out for themselves and then there's a another set that could could do it or at least do better than they're doing if they're taught and I think when I when I became an independent consultant two and a half years ago and started doing Ruby full-time one of the things I told people about why I did it was I'm really just not interested anymore in the big it let's see let's see if we can figure out a way to do okay with a bunch of average programmers I want to go off and see how well you can do with a bunch of good programmers and and I believe that except it sort of artificially splits the world into into two sets that and I think there's some people in the middle that get left behind if we all take that attitude and that would be a shame yes Dave mm-hmm yes yes I agree I agree 100% but that is a as simply as you've laid it out and I agree with you but as simply as you've laid it out is a false dichotomy because I know a lot of people who have had that sense of care for their craft awakened in them when it wasn't there to begin with because they learned skills and saw that there was a better way to do it and and that's what I'm really concerned with is the yeah there are people who just won't and there are people who innately do and I'd like to find I'd like to not leave the people in behind who would love to have the joy in their work that we do and and and could I'd like to not leave them behind so I think the gentleman in the maroon shirt back there is yeah right I I don't think you know the way that that traditional productivity graph is drawn the average developer there is way down on the low end of the skill scale and I think in our industry today the average developer is way down on the low end of the skill scale and that's horrible to see and it's horrible for us and it's horrible for them because they don't get enjoyment out of their work and they're you know a detriment to their organization in many cases and sometimes the kindest thing to do yeah is to tell them they need to find something that they're good at and enjoy and care about and but you know again it's not it's not that dichotomous does anybody back there know if dinner is ready because because I'm over time so I'll take one more question from the cameraman yes okay thank you very much video equipment rental costs paid for by peep code screencasts