Last week, Sandi Metz took time out of her Memorial Day to Skype with me for over an hour sharing her ideas on programming, design, frameworks, learning, and life without if statements. Along the way I found myself frequently laughing over her self-deprecating humor and amazed by her down-to-earth attitude.
AB: So the last time I saw you was at RailsConf -- you won a Ruby Hero award.
SM: How cool is that? Yeah, I had a -- I sort of knew -- they don't really tell you that you've won. What they do is confirm with you that you'll be at the Ruby Heroes awards -- and then you get followup emails that say, "we want to make sure that you'll be sitting near the front."
SM: Right? And so when you get the first email, well, you don't want to presume -- it seems impossible. And so I was thinking maybe they just have finalists, right? Because they really will not say that you've won. And so, yeah, it was cool.
AB: I definitely agree. I thought that was really fantastic and it was very fun.
SM: I mean, I think of people who work on open source projects as being the people who would get Ruby Hero awards. Historically that's what it's been, people who've spent tons and tons of time on software that we all use -- so when they first talked to me, I thought "that's ridiculous, I don't deserve it". I haven't done much open source at all -- I work on my own little apps behind firewalls.
AB: I think that education about open source definitely is contribution in and of itself.
SM: I thought, this is a commercial book -- the book isn't freely available -- and I went through all those reasons why I didn't deserve it. But then I thought: I spent two damn years on this!
SM: [laughing] Yeah, so, it was really cool.
AB: I'm glad that you don't have those doubts, because I think it's well deserved.
SM: I'm just not used to the idea that I deserve it. [both laughing]
AB: So when I saw you there, I knew you were headed off to Paris and it seemed like you had come from about five places.
AB: You're pretty busy right now.
SM: So here's the deal -- I'm going to Toronto tomorrow. When I get back, I'm going to New York the next week, and when I get back the day after that I'm going to Washington. Back to Washington. I was in D.C. last week. I try to just go someplace once a month. I've turned down twenty speaking gigs this year.
SM: I can't even remember the list. I finally quit making tags in Gmail for conferences that I've declined because the list got too long.
AB: [chuckling] That's incredible.
SM: So I turned down a bunch, but I took one per month and didn't really figure out ahead how this would all work. The people who talk at conferences all the time -- like Jim Weirich, he does that for a living. Jim works for whoever it is, not New Context -- they changed their name to Neo or something now.
AB: I think there was a joke on Ruby Rogues about not being able to keep track.
SM: Yeah so I talked to him at Ancient City and I asked him, what is it that you do for a living? Because people who I see a lot at conferences -- I'm wondering, how are they leveraging this into an actual income?
AB: Haha, yeah.
SM: Right? And so he's marketing for them.
AB: Yeah, he's getting the name out.
SM: Exactly. But there's no organization behind me. [both laughing]
SM: Anyway, Paris. They called me at the last minute, but how do you say no to Paris?
AB: I don't think you do. I think that's one of the rules about Paris, right?
SM: And even if you're already overbooked, it doesn't matter. I don't know. I'm supposed to be working on the POODR videos right now.
AB: What's that about?
SM: They want a video series for the book – the people who own the copyright. The people who own it.
AB: Well, that's awesome. What exactly do they want you to do?
SM: Okay, so this phenomena is very confusing to me. They want me to not exactly read the book out loud, but they want me to explain the book in a way that maps very closely to the text. Like, Michael Hartl has a series for his Rails Tutorial -- he's got ten or fifteen hours of video that are companion video for the book. But the economics of this escape me -- for the buyer, I mean. You can go to Amazon.com and get the e-version of POODR for $17 and you could read it in an afternoon. Now, for people who have less experience, there's digestion involved. So they're probably not reading it in an afternoon -- but still, it's cheap and relatively fast. Or you can spend more money on many hours of video and watch it over a long period of time.
AB: I think that, uh, because you're as versed with the material as you are -- as the author and somebody who has studied this for some time -- you're not seeing how great the benefit of additional explanation can be.
SM: [laughing] I am clearly not.
AB: I think that kind of repetition is the kind of experience people are looking for. So the reader gets this new idea, and they think "oh my goodness, I want to know everything about this" and you might feel like it's more of the same, but when the concepts are new, every new example of the same idea helps solidify it.
SM: I mean, I do believe that, I'm willing to accept that -- but really what people seem to want is for me to tell them what's in the book. [both laughing]
AB: I just think that different modes of learning sink in in different ways. But I think there's a sentiment there that I also hear when you speak at conferences -- that that you have this knack for explaining things.
SM: It's like my only skill, it's true. I will totally accept that. Like, I have this leaky thing in my brain where lots of apparently unrelated things get connected -- it has cons and benefits, because I can also say the most inappropriate things, I promise you.
AB: [laughing] Does this ever get you into trouble?
SM: Oh yeah, totally. At the same time, if I let it go, I get really good analogies that help me explain things. A couple of weeks ago, actually, at Ancient City Ruby, two things happened. A guy came up and asked me if POODR was ever going to be on Audible.com --
AB: [makes a face]
SM: -- and I, I did that.
SM: But now that I don't have a job, every question -- I don't just say "that's stupid."
AB: They're all opportunities.
SM: Yes, exactly. So I asked him, how would that work -- it's full of code? I don't understand -- how would you use that?
AB: I think that's why I made the face that you detected. I don't know -- are there tech books on Audible? I was unaware of this.
SM: I didn't even see how it was conceivable. So I asked the guy, why would that be useful? Am I going to read the code? In what way are you imagining that it would be useful for you? And he said that there's lots of explanation in it, and that all the explanation stands alone.
SM: And he does that same thing that we all do -- he lets the audio run until he hears something interesting, and he stops and backs it up and he listens to that part. He said that even if I just said "there's code here" and "there's code here", if there was just a thing where I read it, he'd want to hear it in my voice, all of the explanations, read directly from the book. So, this same day, I got a tweet from someone that said "I just watched your talk from somewhere, is there a transcript?"
AB: So it seems like people really want it all, then. We want written content in video, and video content in written form, and if I could get this to listen to in the background while I'm at work that'd be perfect. So you got a green screen for these videos?
SM: I don't, but I have some software. They don't really want video of me -- they want screencasts -- so that helps. And there's some headshot thing that they want to do in a professional studio that I'll have to go to. So it seems totally lame.
SM: It's completely lame. Like, I've watched a bunch of sample videos -- they're big sellers -- and I just found them appallingly boring. Maybe I'm too just ADD to watch videos.
AB: Well, that could turn out to be an asset for making good ones, you know?
SM: Yeah, well -- anyway, enough about me.
AB: I'm just going to continue to ask you questions about you, Sandi.
SM: Okay, well, I can talk as long as you're asking.
AB: So you were at Duke for many years, and in some of your talks you've mentioned working on very large, long-running applications there. That environment sounds like where you honed a lot of the ideas that you're now writing and speaking about. Can you talk a bit about that time?
SM: You know, the longest running app that I've been associated with at Duke is an app that handles sponsored projects. At universities, faculty do research and that research is sponsored by someone or some business. People who aren't associated with public universities probably are unaware of how much of the money that drives public institutions comes in the form of grants or contracts. And so getting funding is a big deal -- you're working on a project that's funded by a grant, and many of those involve competitions, especially with the government.
AB: [chuckling] Competitions with the government?
SM: Ha, no, contracts with the government are things you'd compete for. NIH wants a cure for cancer and they have an idea about how to do it -- so they put that idea up there, put a bunch of money in a bucket, and they tell everybody go ahead and submit a proposal to get some of this money for research. There can be a ton of money involved. So there's an app at Duke that we wrote twenty years ago in Smalltalk that basically manages how people submit proposals to funding entities. It was a waterfall design, and they put people in a hotel for like a year to figure out what the app would do. It's of massive importance to the institution - it's been through a couple of big rewrites in Smalltalk, segued through a little bit of Java, and now most of it is has been rewritten in Ruby. So this is an app where the same database has been through three different frameworks.
AB: That's pretty cool.
SM: Yeah. So that's a kind of experience where stuff doesn't go away -- you just keep on adding to it and changing it. And for an application like that, the data matters much more than the application itself. The data has long term value over many years, and the way users interact with the data is a skin we put on top of it. So whether it's a fat-client Smalltalk app sitting on people's desktops or whether it's some kind of web app, the frameworks come and go a lot more than the data does. I have a lot of interest and concern in making apps that people can maintain over long periods of time -- making apps that can switch frameworks without losing all the business value and years of effort that we put into them.
And so, yeah, I mean, I recognize that we're all victims or products of our own experience. I have a very specific perspective on what a good app looks like, and it's because I haven't spent thirty years writing apps that we threw -- I mean, if I were part of a startup and the funding was coming and going, and we were throwing apps at the wall and if they stuck they made money and if they didn't stick, maybe we just abandoned them and went on to the next thing -- I might have a different bias. That style is totally legitimate; people write a lot of code that looks just like that. The kinds of things that you care about if you're doing that are different than if you think that your app is going to win and exist for a long period of time.
AB: If it has to win.
SM: Yeah, it has to win. That's probably the biggest example of an app that's lived a long time but there are tons of them. There's app after app after app at Duke that has been around a long time, and the data matters. We think of the app as being embodied in the data, not embodied in the framework. For example -- that fat-client Smalltalk app? Parts of it are still in Smalltalk.
AB: Parts of it are in Ruby and parts of it are in Smalltalk?
SM: Yeah, so the first part of it that went on the web was the faculty end, and so right now there's a multi-year project underway to get all of the administrative parts of that app on the web so they can quit paying Smalltalk licensing fees. They're trying to get rid of Smalltalk because open source has won so thoroughly that people are a lot less interested in paying annual licensing fees by the seat. Despite the fact that, with Ruby, strangers improve the software such that we have to do upgrades regularly -- and that's a cost that people complain about for open source -- the price of open source is still far lower than the price of closed source.
AB: So you were beginning these apps -- did you work on them from the start?
SM: Yeah, for many of these apps I was there at the beginning.
AB: Do you feel like some of these lessons you learned came from doing some of these things the hard way, or were there mentors with you at Duke at the beginning who were able to help steer you from their own experience?
SM: No, we learned it all the hard way.
AB: [laughing] Amazing.
SM: Well, it was back in the day. When we first started, we'd go to the Smalltalk and OOPSLA conferences, and so we were aware of people like Kent Beck, Rebecca Wirfs-Brock, Robert Martin. There was information out there about how to write object-oriented code, but we didn't understand any of it. When I think now about what I knew then, it's a miracle anything worked.
AB: You needed more examples and videos, Sandi.
SM: [laughing] Maybe. I mean, there was a lot of guidance in the fat-client MVC Smalltalk frameworks that we used. Like in terms of being exemplary, they were very exemplary. So there was this browser that you'd go write code in, but the browser itself was written in Smalltalk, and so anything you couldn't figure out how to do, you could just look at the source code. If you could think of a thing like it in the browser, you could go and look at the source code in the browser and do it -- so we learned a lot from the tools we had.
AB: Do you think that there are lessons from the Smalltalk community that have not yet reached the Ruby community?
SM: Yeah. I don't want to -- I am in no way a Smalltalk snob! If I was, I'd be writing Smalltalk today, right? Smalltalk didn't win, and I don't think it's ever going to win. It missed it's chance because it was closed source, but Ruby is -- I mean I don't want to say it's like Smalltalk but better, because it's not quite. I mean, there are things I can do in Smalltalk that I can't do in Ruby, which I find a little bit frustrating, and I'll give you -- should I give you an example of that?
AB: Yeah, that sounds fantastic.
SM: Okay. So in the book, there's Ruby source code to explain a bunch of stuff and, you know, I write Ruby every day, but the truth is I'm very much not the best Ruby person around. So I have bias. I'm so biased by my Smalltalk background that I made assumptions about things that ought to work in Ruby, and when I tried them and they appeared to work, I believed that they were right. One of those things was to subclass Array.
SM: I just did it. I just assumed that if I have a thing that's sort of an array -- if I want to add behavior -- I'll just subclass Array. I didn't really understand that there were very specific reasons why doing that in Ruby was a bad idea. I have a lot of bad habits left over from my little silver bubble that I lived inside -- one is that I tend to think I can use everything as a first class object, so I have to be careful about that. The other is, well I'm used to living in this world where it's so closed source that you don't really share code with anybody else, so I'm far too likely to just rip open a base class in Ruby and make a change in it. This world where we're all collaborative and you should be exercising a little care about stomping on others messages, We were writing applications, not frameworks, so as an application writer you're at the end of the line. If you make base class changes to String, your team knows that.
SM: Yeah. There's many ways in which that can go badly. We did it for years in Smalltalk without a thought and never had a problem ... but there's not a whole gem ecosystem for Smalltalk. You're dealing with the library or you're dealing with your own code. But because Ruby has won -- and because Rails has won -- you have to take the rest of the world into consideration when you write code in a way that we never did when we were writing Smalltalk. Anyway, the thing about Smalltalk, the example that I always give people is -- I don't want to get too nerdy here -- let me see if I can explain this quickly and sensibly. Imagine you didn't have an
if statement. Imagine, Andy.
SM: Imagine there's no
AB: I can keep my eyes open, right?
SM: [laughing] You can. So yeah, there's no
if statement. So: how do you switch on booleans if there's no
if statement? It seems impossible, doesn't it? This is not a test. Does anything leap to mind?
AB: Something like instantiating an object based on something you know.
SM: Uh, huh. So imagine this: imagine you had a
true object -- which you kind of do in Ruby -- there's a
true is an instance of
TrueClass. And imagine it implemented two new methods, right? Actually, let's leave
true out of it for a minute. Imagine yourself as an object. You're an
Andy and you're a positive guy.
AB: Okay, this is a lot easier.
SM: This is a lot easier. So you're an instance of
Andy, and because you're a positive guy you believe that everything is true and nothing is false, right? You're just that way.
SM: So let's imagine that I'm negative. I'm negative Sandi.
AB: It's getting harder to imagine again.
SM: I'm just the opposite. I believe that everything is false and nothing is true. Alright? Now, if I wanted to be the Sandi object, the negative Sandi object, I could implement an
if_false method, and they could take a block. So if you sent
if_false(some_block) to me, I would always say, sure it's false, right? Because I believe that everything is false.
AB: You are False.
SM: Yes I am. And you, positive Andy, are just the opposite. If someone sends you
if_true and passes you a block, you evaluate the block, but if they send you
if_false you just ignore it, you do nothing. Right?
SM: And so, if you just have some way to make that boolean, and you can get the language to evaluate that to an instance of that class, you now have an object that will always evaluate the block they get for true or ignore the block they get for false appropriately.
So we're talking about having true and false objects, and sending them messages. In Smalltalk, you don't even have control structures in the language -- you just have objects that have messages. And then your whole world is different. The syntax is to send a message, and there's nothing else. So you can imagine how it would shape your thoughts if you grew up in an object-oriented language like that. And how if you came from a procedural language to a language like Ruby where you have those control structures how it's easy to hang on to the procedural parts of your past.
AB: The procedural past.
SM: [laughing] Yeah.
AB: When did you know that you wanted to be a programmer?
SM: Oh, I don't know, like, I'm a woman of a certain age, and that age sort of pre-dates the profession.
AB: We don't need the year -- I just mean when in your life.
SM: I was a failed music student looking for a job until I could decide on a new major when I ran into the local vocational technical school at the mall. At the time, I thought vo-tech was for boys who were going to do auto body work underneath the football stadium, but I happened to be with someone who said, oh, vo-tech schools, they'll teach you how to make money, they'll teach you a job. And I was working at a WalMart-ish kind of thing -- so I visited the vo-tech school and saw that they offered drafting classes. I thought drafting could be cool, I can be an architect, right, I'd love that. So I took the little pre-test and they insisted that I sign up for data processing.
AB: They insisted on data?
SM: Yeah and I argued with them because I didn't even know what that was -- I mean this was, 1979, nobody was a 'programmer'. So they say I belong in data processing, and I didn't know a soul that -- I mean, this was in the days of punch cards in the IBM 370. This was before you get a degree doing this -- you couldn't really go to school, The reason vo-tech schools were teaching it was because employers needed programmers and they couldn't get them. But this was in the era of pocket protectors. I didn't know anybody that was a computer programmer, and it just seemed like the most boring thing I could imagine. I'm going to sit a desk and type all day long? That's insane. And so I had a big argument with them and I told them no, but they were really insistent. And so I went home -- but I was actually living with someone at the time who had done a little programming, but I didn't know it. And when we were washing up after dinner, out of the blue he said, "you know, just listen to them -- I think you might be good at data processing." And on day one of the first class, we wrote three FORTRAN programs and I fell in love.
And that's when I knew I wanted to be a programmer, but it was totally an accident. I never looked back from that point on because I thought, wow -- this is the job? You get to do this for the job? You get to play with logic puzzles all day long? How can this be work? So yeah, it was an accident.
AB: Do you feel like there's anything outside the context or theme of your book that you'd like programmers to know?
SM: I have this really strong desire for us to demystify -- to simplify our explanations to one another. And I think the book is an instance of that, or at least an attempt at that. Whether or not it has succeeded is of course an exercise left to the reader, but I want -- let me just say this -- I have a whole pile of technical books on my desk that I cannot read. I know that there are amazing ideas in them, and every now and then I crack them open -- and now more and more, because people think now that I have read everything.
AB: All of it! Everything!
SM: All of it, right? And so I have all those books -- I do work on them more rigorously now than I ever have, but I find it very tough going. And I don't know what it is about our community or our history, but why did things have to be complicated? Right? I mean, they're not. They're not innately hard, I don't think, and yet ... I don't want to assume that people make overly complicated explanations in order to keep people from understanding.
AB: No, I don't think so either, but it seems to be a thing that could almost come across that way sometimes.
SM: Yeah. They're not bad, they're not evil. Some of them come from an academic world where it seems like maybe there's a circle where everyone understands those explanations. That clearly seems true, right?
AB: For sure.
SM: But then where does that leave the rest of us? Because I think that pyramid is really wide at the bottom and pretty narrow at the top. And somewhere near the top are the academic folks who get what they're talking about, but I can promise you that I don't. And so that struggle of trying to figure out what they mean, what they're saying, how it applies to me -- if I could wave a wand and change the world, that'd be the thing I would change. I'd make people who have smart ideas able to explain them to the rest of us so that we can understand them and apply them usefully. It feels to me like there's a big gap. It feels like we're failing each other in this business. It feels like we're failing to provide.
AB: Are you referring specifically to books and educational material or about communication in our industry in general?
SM: Yeah, I don't know. One specific case is definitely the books. I don't know about the general case, because I don't think I have standing in that argument. I don't have standing to speak to that -- it may be true. But I can name some books that I found very hard going to begin with that I still think everyone should read. Everyone should read and understand the true meaning and techniques of Refactoring. That means going all the way through the Martin Fowler book, or going all the way through the Jay Fields Ruby version of it. And those books aren't terribly hard to read -- I just find that their story is uninspiring, because it's just detail detail detail detail detail, right?
AB: Yeah. I think that can happen anytime you have a greater point to get across and you know you need some code -- that can be a challenge.
SM: Yeah, yeah. And I'm not saying that they didn't have a really difficult challenge. Like, how do you tell a story inside the Refactoring book? [laughing] I don't know -- it seems kind of impossible, doesn't it? But I just had a hard time understanding the bigger context when I first tried to read that book. Another book I think is really useful and has tons of amazing ideas in it is Eric Evans' Domain Driven Design. But I just have a very hard time grasping the details. Again, I don't want in any way to seem critical, because I think the ideas are absolutely amazing and I think we'd all be better if we all read it and understood it -- but that's a big step. The reading and understanding is difficult. But I want us to get it.
I feel there are a lot of arguments and tension right now in the Rails and the Ruby community around this idea of design. How are we going to do design -- how are we going to arrange code? And I so firmly believe that there are ways to understand the consequences of the choices we make about code arrangements -- and that knowledge will enable me to choose the consequence I like. So it doesn't seem like design is a bad thing to me. I just want people to get it so they'll know what they're picking. And yet it feels like there are a lot of heated arguments over different alternative arrangements, and the parties involved may not necessarily understand the consequences of all the choices they're fighting about. It just feels like we could have a higher level of conversation and produce better quality code if we all understood that.
AB: I think a lot of readers are excited about this, and that there's sometimes some frustration with applying these concepts within Rails. I don't mean to speak poorly of Rails, because it's provided me a lot enjoyment as well as a livelihood. However, many people get excited about design and SOLID principles, and then get stuck. Like, how does a Rails controller or ActiveRecord model conform to the Single Responsibility Principle? So I think a lot of readers are very curious about this and are wondering ... what does a Sandi Metz Rails app look like?
SM: So here's the thing. Let me just say this first: if I were not a slacker I would write a blog post about this, but I am, so I get this question all the time. People are always telling me they can totally see how object-oriented design matters in Ruby, but they're writing Rails, and so what should they do -- and I don't necessarily feel qualified to answer that question officially, but I do have opinions. I definitely have opinions. And so I think of myself as someone who writes 'applications that use Rails', not as someone who writes 'Rails apps' -- and I have a different definition for those two things. Like you, I love Rails. And I think if you have a Rails app, as opposed to an app that uses Rails, then the Rails conventions are perfect. And when I say 'Rails app', I mean an app where a GUI pretty much maps over a database.
SM: Right? And so in a Rails app, there's an expectation built into the framework of this kind of pattern: a request comes in, and it's going to be a RESTful route that will wake up a controller action, that action is going to know about the name of one class, that class is going to be its model, that model class is going to be a subclass of ActiveRecord, and the controller action is going to know the name of that class.
Let's ignore the index action for awhile -- let's say we're talking about the
show method. So it knows the name of the class, it's got some id, and there's a little factory in that class --
find is a factory method. It's going to generate a new instance of the class, that instance is going to be put in a single instance variable, and that single instance variable is going to be passed back to the views. That's the simplest kind of Rails app. The controller knows the name of one class and it passes a single instance variable back to the views.
Now if I have a more complicated application -- which lots of people do; it's a tribute to the strength and flexibility of Rails that many people write apps that use Rails when they don't have the simplest kind of Rails applications. So in that situation, let's say I have a controller action that doesn't map one to one to an instance of an ActiveRecord model. Then really what I want my controller to handle is some kind of procedure that's going to require the coordination of a whole bunch of ActiveRecord models. So I have a couple of choices: I can put all the code in the Rails framework -- I can make my controller know a whole bunch of classes and have all the logic for all the coordination between them and I can set a whole bunch of instance variables and pass them back to my view. So I can basically break the Rails pattern. Or, I can honor the Rails pattern by making up new objects, shoving the edges of the framework apart, and putting new objects in the middle. Now when you do that, all of those objects in the middle obey all those standard rules of Ruby object-oriented design, and the framework does nothing but let me deal with input and write to persistent store.
So I write apps that use Rails, and I put very little logic in subclasses of the Rails framework, but I follow the Rails pattern. I want my controllers to know the names of two classes: the service business object, and the presenter object. And so I'll often instantiate a presenter class in my controller that takes my business class as an argument that then takes
params as an argument. That lets me honor the Rails pattern of knowing the name of one business object while at the same time honoring the Rails pattern of having one variable to pass back to the views -- but it lets me get all of my logic out of the Rails framework classes so that I can do standard Ruby things.
This kind of pattern is easy to test, I can use dependency injection, I don't have bunch of logic in helpers or controllers, I can write a test suite that evolves -- and because I completely trust that the Rails objects behave correctly, I don't have to do much in the way of ActionController or ActiveRecord tests if I can get all of my business logic out of those things. I can use small, easily composable objects that sit in the space between the edges of the framework, and have fast running tests about objects -- and the next time my app moves from Smalltalk to Java to Rails or whatever, all of my logic isn't tied up in the framework so it's easy to reuse or port.
I know that's not much help for people who's apps are just absolutely insanely complicated. When you're starting with a greenfield app, it's easy to keep your logic away from the Rails framework. In a legacy app that has a lot of entanglements, then the only way to fix them is just to nibble away at them. When you add new code, don't make it worse. When you touch code, make it better. And my advice to everyone -- whether you're dealing with a Rails app or a Ruby app -- is that problems can be solved by breaking them down into smaller pieces. So break things down into smaller pieces in your Rails app, and quit putting logic in controllers. Make your ActiveRecord models smaller. There's a lot business logic that's not really part of the framework, and if you can get it out of the framework and into objects you own, then everything gets easier. There's no reason our Rails apps have to make us suffer even if they're big.
AB: Is there such a thing as Impractical Object–Oriented Design in Ruby?
SM: [laughing] I think that there are things that people call design that seems very impractical to me. I mean, the things that give design a bad name by definition are impractical, right? I'm not without sin, though. Most of us are nerds and we want to follow that flight of fancy and do the cool thing, but you've got to put a leash on yourself and not overengineer things. We owe it to the people that pay the bills to not indulge ourselves. If it's your money, you can do whatever you want for the sheer fun of it, no matter how big a waste of time it is -- but in the big world, we have ethical obligations to the people who are paying for our time to provide value.
I don't think people overdesign because they're evil -- it's more of a symptom of having more care than experience. They're trying to do the right thing, and there's always this tension between making the best decision given available time and resources, and learning. It's taken me a long career to get comfortable with 'good enough' -- to leave code that's not very pretty, to leave code that I feel a little bad about, to leave code that's not quite right. But I've learned that doing too little is almost always better than doing too much. Almost always. It's much harder to change an abstraction that's wrong than to eliminate duplication.
And so there are tons of impractical things that are often justified in the name of design. By my definition, I don't think of overdesign as being 'design' at all, whereas I know that there's a bunch of people in our community who think that the word 'design' means overdesigned, as if anything that could be called 'design' is bad by definition. I use design to mean 'however the code is arranged', and so, yeah, there's plenty of impractical design, depending on what definition you're using.
If you think of all 'design' as bad, then it's all impractical. I would say just the opposite -- all design is good and that anything that is overdesigned is not designed at all. It's all semantics.
Sandi Metz has 30 years of experience working on projects that survived to grow and change. She’s the author of the recently published Practical Object–Oriented Design in Ruby and (as all who read the book know) an avid cyclist. Fundamentally, however, she is someone who writes object–oriented code.