Today on The Rabbit Hole, we are doing another remix, this time going back to an episode with Steven Solomon on how the DRY principle is misunderstood. Steven has been a programmer since 2007 and has been fortunate to work in many contexts. In this episode, Steven unpacks what the DRY principle is and clears up some common misconceptions about it. Commonly when developers see two lines of the same code, they are tempted to extract that into a method based on their understanding of DRY-ing. Steven explains why he understands the definition to relate more to ideas than methods. We also look at why and when to think twice before you dry, some of the situations that require DRY-ing, and what to do when the code gets too DRY. This episode is a fresh take on a widely misunderstood concept. Tune in today!
Key Points From This Episode:
- Steven unpacks what the DRY principle means and common misconceptions.
- Understand how to apply the DRY principles to ideas and not only methods.
- Find out how only responding to duplicate code can land you in hot water.
- How Steven decides when code needs to be ‘DRY-ed’ up: find an expert!
- Two questions to ask when you can’t find an expert to help DRY up your code.
- Steven gives some examples of when you apply the two by two quadrant model.
- How to build separate objects rather than just DRY-ing up code by default.
- Why having an idea that is spread out over the system is the worst-case scenario.
- The ways that Mike, Dave, and Steven have used DRY in their own work.
- Understanding divergent change and how it relates to DRY.
Transcript for Episode Remix: The DRY Principle is Misunderstood with Steven Solomon
[0:00:01.1] DA: Hey folks, Dave here.
[0:00:02.8] MN: Mike here.
[0:00:04.0] DA: Hey. I thought you were on vacation?
[0:00:05.4] MN: No, no, no, no. That was – I’m back.
[0:00:09.2] DA: Okay, good.
[0:00:10.1] MN: I’m probably back.
[0:00:11.8] DA: Well anyway, you know, we’ll still like, put out this remix episode here so we’re going to rerelease an episode here. Episode number 113, ‘The DRY Principle is Misunderstood’ with Steve Solomon which I guess is a little bit ironic because repeating the episode, don’t repeat yourself but –
[0:00:32.7] MN: Man, yeah, we’re doing it. We’re repeating ourselves, aren’t we?
[0:00:36.8] DA: Not even twice.
[0:00:37.8] MN: Not even twice. Off air, we talked about the opposite of DRY is damp.
[0:00:45.0] DA: Yeah, sometimes It’s okay to be damp.
[0:00:47.6] MN: What was it again?
[0:00:49.4] DA: Descriptive and meaningful phrases.
[0:00:53.1] MN: This guy damps.
[0:00:55.1] DA: I’m a big fan. But yeah, you know, DRY is important and you got to understand it for what it is, you can’t be a zealot, I really like this episode with Steve.
[0:01:07.3] MN: Right, I think a lot of engineers see like one piece off duplication like just one thing and they’re like, “We have to bubble it up and make it a constant and all these thing!” And like, they’re really adamant about that. But there are instances where repeating yourself might do you a solid for the sake of readability of certain things. We get into the weeds of like, to figure out when are those times when you should think twice before you DRY, I guess. I thought it was pretty insightful. Steve Solomon, friend of the show, always welcome.
[0:01:42.5] DA: Take a listen to Steve, see what’s up.
[0:01:45.8] MN: Hello and welcome to The Rabbit Hole, the definitive developer’s podcast in fantabulous Chelsea Manhattan. I’m your host, Michael Nunez. Our co-host today.
[0:01:53.8] DA: Dave Anderson.
[0:01:54.9] MN: Today, we’re talking about how the DRY principle is misunderstood.
[0:02:00.0] DA: Yeah, I’m sure I’m sure I’m getting it wrong but luckily we have a special guest here who is anything but dry to help us through it.
[0:02:05.0] SS: Today we have Steven Solomon, how’s it going Steven?
[0:02:10.1] SS: It’s really good, thank you for having me on.
[0:02:11.3] MN: Steven, tell us aa little bit about yourself?
[0:02:13.5] SS: Year, I’ve been a programmer since 2007. I’ve been very lucky I got to work on a large variation of different types of projects. I’ve worked in compile languages and really recently I’ve gotten a lot into Ruby on Rails and beginning to play with Elixir so I’ve seen this kind of wide swath of different programming languages as well as different industries.
[0:02:37.7] DA: Doesn’t matter which one you’re using, everybody’s trying to try things out.
[0:02:41.5] MN: Yeah.
[0:02:41.9] DA: It’s got to be DRY.
[0:02:43.7] MN: For our listers who may not know, what is DRY? DRY.
[0:02:47.3] SS: The DRY principle is something that was first written about by Dave Thomas and Andy Hunt and their book Pragmatic Programmer. Yeah, there’s actually a new version coming out so people should check that out. In that book, they define the DRY principle as every idea should have a single unambiguous authoritative representation in a system. It’s a bit wordy.
[0:03:12.8] DA: But basically, you know, if you look at code and you see two functions that have the same line of code, then you should just extract that into a method, right?
[0:03:21.3] SS: That’s often what we talk about in our industry but their definition really seems to imply that it’s about not duplicating ideas.
[0:03:29.7] MN: Right
[0:03:29.9] DA: Right.
[0:03:30.6] MN: That’s very interesting.
[0:03:31.5] DA: A bigger concept maybe.
[0:03:35.7] MN: You often see DRY and people spell it out where it’s like, don’t repeat yourself and people believe that – don’t repeat the function, the methods that you're doing. But as you mentioned is not just methods but the idea that is encapsulated by the methods, don’t repeat those things.
[0:03:50.7] DA: I feel like when you hear about the DRY principle, you’re like, “I get it, this is so powerful.” I only have to write it once and then you just refactor everything, you know? Into a function somewhere and then you try and trace through your code, you’re like, “Oh, god, what have I done?”
[0:04:08.4] MN: I mean, Ruby might be a little bit difficult, I know I use IntelliJ for Java and you could just like command click your way back to the beginning of time. To find the beginning of that function, it’s repeated often.
[0:04:23.0] DA: You found those refactoring tools. Been using intelligent by term and man, just extracting all those methods feels pretty good.
[0:04:31.1] SS: I cannot program without a JetBrains product. Also, I don’t work for JetBrains.
[0:04:37.6] DA: Yeah, they’re not paying us either. Conrad really, a friend of the show, Conrad Benham really sold me on it for a long time and now I get it.
[0:04:48.0] MN: Yeah, the idea – we often hear about the DRY principle and we experience engineers, were often talk to and talk to junior engineers about how you shouldn’t repeat yourself so that’s something that like gets past on as knowledge but people often just see it as just like methods. Is there like a mindset that you care to elaborate to separate it from just methods and on to ideas?
[0:05:14.6] SS: Yeah. To kind of paint the problem a little bit more, a lot of what I’ve seen on projects I’ve been working on have been this scenario where people like extract things way too early and eventually, requirements require those two things to be different and all of a sudden, there’s this nested conditionals or case statements or even multiple different random objects or functions that are all injected in the same moment.
It becomes this really tangled mess that becomes like untraceable.
[0:05:50.7] DA: Right. And as you’re probably not the person who extracted that method to begin with, “Okay, that person was smarter than me and they had a reason for doing it so I must just need to take this other level of abstraction, just jam it in here, just put on the if statement.” Which I think we talked about a little bit with Jacob O’Donnell.
[0:06:11.4] MN: Yeah, that was the episode Death by a Thousand IFs. If you have the idea, you had this idea, this class, I think you mentioned before in time, the ‘god class’ that just constantly is in control of everything and you don’t’ know the context in which the individual created this class with all these variations and whatnot. You are leaving it up to the developer to have also have some context in those changes. But then, ultimately, it may have been too DRY, I guess.
It was dried way too early than it should have been.
[0:06:49.4] SS: Yeah. They’re often times like I’ve made this mistake is just responding to seeing duplicate code and thinking that’s as the principle goes and then getting into trouble. And then now, you have to find a way to extract out these separate things because you know, you’re in an application where you’re pricing grocery items and meats have a different set of business logic than produce does.
As long as those things are both dependent on a shared thing, you’re never going to be able to do it easily. You could hack it in there but you’re going to be worse off.
[0:07:27.0] DA: Right, when those requirements come in. You’re really going to be in a tough place.
[0:07:32.1] MN: Yeah, but then, before jumping in and like, thinking about DRYing up everything, when do you look at a piece of code and decide whether it needs to be dried up?
[0:07:45.1] SS: The number one thing that I try to do is I try to advocate on my team to go to a product person or a subject matter expert. They’re usually someone who has been in the industry for a number of years, whatever they are, if you’re in groceries, there’s like the grocery expert and he’s been there for like 20 plus years or if you’re in finance, there’s someone who has been there for 12 or 15.
The other person who has a gut instinct and experience to be able to tell when things should change at the same time and what things are truly related and I think that’s the best advice I think you can do is just find who that person is and drawl out the business objects, not the layers of your architecture and presentation and not designed patterns.
[0:08:32.9] DA: My dead house. The subject or whatever.
[0:08:35.3] SS: Yeah. Leave those things out of it but like, conceptually, what are the moving parts that facilitates that functionality?
[0:08:44.6] DA: Yeah, definitely.
[0:08:46.3] SS: Over react. It will be like, “What is that?” I was actually talking to a stake holder a few years ago and she did this wonderful reaction and it was, “Do you even know how this is supposed to work?”
[0:09:03.3] MN: Programming or –
[0:09:05.4] SS: The system. Describing her business domain and you know, sketching it out on the white board, just in complete shock at like what was – what the mechanism inside the code was to facilitate that. The concepts were not recognizable to this person who was an expert.
[0:09:22.8] MN: Right, sure. There’s conversations like – or rather, there’s books like Domain- Driven-Design that talks about how your code should reflect the real life situation or that in which the expert would be able to understand even like the diagrams and whatnot. I think your comment about going up to the PM to ask questions is a great point because we often see like a feature story and then we’re really quick to just run and program.
We love to do, we get caught up in like design patterns and stuff like that and try to make it look like elegant code, when in reality, it should reflect real life. I think the expert is the person that would bring you down to let you know what real life looks like and how we should implement that.
[0:10:15.7] DA: There should be like some kind of an overlap really between nice and good code, an elegant code and in this domain focused concept.
[0:10:25.8] SS: Yeah, there are definitely moments when the domain could be tightened up because you know, often times, when they’re automating something, it’s never been run before. Often times, it hasn’t run before so it hasn’t had to be that accurate, it’s kind of like – it could be conversationally accurate but not accurate enough to run with bullion logic and work can be fuzzier. That’s really –
[0:10:54.6] MN: Detail and the specification you got to get to get there.
[0:10:57.7] SS: Exactly. That’s really the starting point, that’s the number one thing I think a team should be doing. But then there’s a few other techniques if you can’t find that person or that person doesn’t exist like if you’re in a startup.
[0:11:10.6] MN: Right, I mean, I was going to say you mentioned a food expert and I like to think that I am a food – I’ve been eating for the past 31 years and know my way around the supermarket, I guess.
[0:11:19.5] DA: Lots of good breakfast.
[0:11:21.5] MN: Lots of it. But suppose if you can’t find – you don’t have a PM as you mentioned, you could be working at a startup or you know, you yourself are building a product at home with a pet project that has gotten a lot bigger than a pet, what do you do when you don’t have the resources to ask an expert about something?
[0:11:43.9] SS: What I do in that context is I ask myself two questions and I didn’t come up with these questions, Ken Beck did. Seems to come up with a lot of wisdom in our industry.
[0:11:53.2] MN: Yes.
[0:11:53.5] DA: Some good tweets there.
[0:11:54.5] MN: Yeah.
[0:12:00.0] SS: He wrote this blog post called Bits versus clumps versus just right, and he lays out these two questions. The first one is can you reason about two ideas separately. So, going back to that grocery store example, you know looking at my backlog and looking at my context I can say, “Well here is these changes coming up for produce and those produce changes are not supposed to affect meat. There is no stories in my backlog to affect meat.”
So, it is like I can reason about these two things separately. It is clear that these things are about to have to change for totally different reasons and then he tells you to ask a second question and that puts it into two by two format like a grid, row and a column.
[0:12:40.9] MN: Okay, everything is a two by two column what is like a squares in four places. So, what is the other question?
[0:12:47.6] SS: The other question is, are those things actually separate in the code? And then from there, you can really decide what you need to do.
[0:12:56.3] MN: I see.
[0:12:57.2] DA: So, thinking about where the business value is clumped versus where the actual implementation is organized?
[0:13:05.4] SS: Yeah, so like an implementation that is tied together but is going to change for separate reasons is going to be very painful to change. And often times, if you have any successful system it is going to be big, hairy and complex. So, there is going to be a lot of threads to try and pull those ideas apart.
[0:13:24.1] DA: Yeah, so what is an example of something like that like where do we live in all of these quadrants? Take me on a tour of the good and the bad and the ugly.
[0:13:35.2] SS: So, there is the scenario like you want me to go through like the two by two in which –
[0:13:41.3] DA: Yeah, I am trying to visualize it like what are some examples that we could concrete this with a little bit? So, I guess like if you have your business value and your code concentrated, like if you are saying yes to both of those question, then that sounds like you are in a good spot.
[0:14:00.0] SS: Yeah you don’t do anything.
[0:14:03.0] DA: So, you have your vegetable object and your meat object and they are just separate and they all do the things they need to do and you are in a happy place.
[0:14:12.9] SS: Yeah, so that is a pretty good scenario. Another scenario is your vegetables and meat object are tied together but the business value is separate and that is a scenario where you need to separate things. You need to make sure those model reality.
[0:14:28.6] DA: So like in that case, if there was a new requirement for meat like the FDA changed their regulation and you can only have meat on the shelves for two days or something then you’d have to change vegetable code too and that would feel a little bad.
[0:14:43.0] SS: Yeah. Or worse, if there is any kind of government restrictions around vegetables now you have to balance like, “How do I fend off the meat, government restrictions so that it’s okay?”
[0:14:56.2] DA: I’ll just tear up some of the Mexican tomatoes.
[0:14:58.8] MN: And the guac and the avocados. Oh no, not the avocados.
[0:15:02.8] DA: Goat cheese is going to shut down.
[0:15:04.1] MN: Oh no. So keeping in mind of all these different complexities between these two objects, we would sit down and then wonder how do we want to build these two objects? Rather than just DRYing up all the time like, “Oh yeah they’ll have government restrictions so we’ll just DRY that up.” But then the government restrictions would be different depending on whether your vegetable or meat for example.
[0:15:30.9] SS: Yeah, letting the domain be the thing that drives whether or not something is actual duplication and not the code happening to look similar if that makes sense.
[0:15:41.2] MN: Right.
[0:15:43.6] DA: Yeah definitely because you can see it also fall into another quadrant where like everything is all clumped together but that is fine because those things need to change together like vegetables and meat for some reason are exactly the same. We don’t worry about it. Or like the way that our business cares about our vegetable and the meat like doesn’t have any relevance.
[0:16:03.3] SS: Yeah, there is one other scenario we didn’t really talked about in that space that Ken lines up and says that it is the worst scenario you can find yourself in it.
[0:16:11.4] MN: What is the worst one? We need to talk about that one go ahead.
[0:16:14.5] SS: Yeah, so the worst one in his mind was you had an idea and it spread about the system. So, like if my logic for calculating meats, there is no way to change that in one place and I have to change it all over the place and it’s this tangled web and it’s just there.
[0:16:32.3] MN: Oh no.
[0:16:33.2] DA: Just sprinkled all over the place.
[0:16:35.3] SS: Yeah.
[0:16:35.8] MN: I got to pull out the shotguns and then go around the whole code base to make this change. Change there, boom, regulations here, bash it.
[0:16:47.4] DA: Right and then added 20 lines of code, changed 15 files.
[0:16:53.4] SS: Yeah and it is really easy to do especially with find and replace, oh my gosh like if you know what you’re searching for you are good enough at generating some RegExr.
[0:17:03.7] MN: Oh yeah.
[0:17:05.3] SS: You know I have seen some crazy stuff get replaced.
[0:17:09.2] DA: I feel like my weakness at RegExr is actually a benefit sometimes because I am like, “Nope, too lazy. I am not going to do it.”
[0:17:18.2] MN: Change all the thing. Nah, I’m good. Don’t worry about it. I mean and IntelliJ I mean we are not paid by idea but ItelliJ does a really good job at find and replace and depending on the language you are using. So that perhaps.
[0:17:30.6] DA: If they wanted to pay us, we can do a fake advertising.
[0:17:32.6] SS: Yeah, well they just made it even worse because now they have this thing called structural replace. So, you can define like the attributes of like I said of Java and structures and be like, “I want you to take that structure and map it into this structure.” It’s like yeah, so that exists.
[0:17:50.6] MN: Oh man that goes shotgun surgery tomorrow at the clinic. It is going down.
[0:17:56.6] DA: So much power.
[0:17:57.6] MN: Too much power. So, the idea of DRY isn’t just as we discussed, just functions that were trying not to duplicate. So, we have to ensure that when we are given new feature but there is some of the thought behind designing it and not going stir crazy in making it as DRY as possible.
[0:18:21.2] DA: Do you have any personal experiences about how you’ve tried to applied DRY?
[0:18:26.2] MN: I mean I often find myself like trying up methods and functions but I try not to do it. There are often times where repeating yourself just makes sense because it is just easier to read the code and then this is something me and Dave spoke about earlier in life when we were talking about refactoring and I think the idea that you could go into this refactoring craze and DRY everything up can often lead to more confusion and being able to read a piece of code that is duplicated twice I think.
Like the limit is over two then you’re like, “Okay this could read better if I just gave it a better name and then I took all the functionality and put it in the method.” But yeah, that’s my limit. If it more than two, then I’d do it with full blown DRYness in that regard.
[0:19:17.8] DA: Yeah, I mean I feel like I am getting addicted to DRYness for whatever reason like using our spec especially with let blocks and all of those. Those are new things to me I am like, “Oh everything can be DRY. Everything can be this whole crazy chain of things that get spun up by your test fixtures.” And then it is like, “Oh wait, oh yeah.”
[0:19:41.6] SS: A shared examples are you know, that you can abstract your tests.
[0:19:46.0] DA: Right yeah, exactly like everything is acting on subject and it is one line long and it is like, “Oh my god I am so good at this” and then someone else looks at it and it is like, “Oh wait, I don’t understand.” This is like maybe it should be this DRY.
[0:20:02.9] SS: So, the whole thing here is the DRY principle was developed to combat the smell of shotgun surgery. I don’t recall if Dave Thomas and Andy Hunt laid it out as that but it is really what they are trying to fight. There is something else and it is the other end of the spectrum, it is divergent change and I often don’t hear people talking about that as it applies to their code bases.
[0:20:28.2] DA: And what does that concept mean?
[0:20:30.2] SS: Divergent change is another code smell that is laid out in Martin Fowler’s book, Refactoring. This one is all about changing the same place in your system over and over again for different reasons. So, it is kind of the super, the god-class if you will that’s everyone goes in and no matter what the new feature is, you got to change the spot and tweak this logic and add a new case statement.
[0:20:55.1] DA: Yeah that is like the violation of the open close principle in solid, right? Where you are like you have to – it is not closed for modification.
[0:21:04.3] SS: Exactly.
[0:21:04.9] DA: You got to go and you get the shotgun out and you modify it. Yeah, I feel like we should have that show where we go through solid principle sometimes. Some of them are like filly bits like I kind of need a refresher on that. But you know it is interesting how these can all tie together and these things that your code has been telling you when you’re pulling it apart and trying to put some of the new features into it, you just have to listen into it and know what the right path is to go down to fix it.
[0:21:35.8] SS: Yeah, a lot of these concepts overlap. I think of it as there’s these different people and they all have different ways they look at these things but they are all hinting at the same problems like single responsibility principle and can back for simple rules of design and the DRY principle and solid and all of these things are just layered on top of each other as different ways to slice the same problem.
[0:22:03.8] DA: Right, yeah different ways. It is important to have that language so you can point at the new ounce of what is specifically the indication of what’s whacky in this particular case. They are nice tools to have in your toolbox.
[0:22:19.1] SS: Yeah definitely.
[0:22:19.9] MN: Steve, how can people contact you?
[0:22:21.3] SS: They can reach out to me on Twitter @ssolo112.
[0:22:28.8] MN: Awesome and you have a talk coming up, right?
[0:22:32.4] SS: Yeah, I am speaking at NYCRB about the same concept, the DRY Principle being misunderstood and that is on June 11th.
[0:22:40.8] MN: At 7:30 PM?
[0:22:42.1] SS: 6:30 PM.
[0:22:43.3] MN: 6:30 PM. So, if you are listening to this episode that means it is today.
[0:22:47.8] DA: Oh my God. Get out there!
[0:22:49.5] MN: Yeah you got to go, show support, show some love. Steven Solomon. Thanks a lot man.
[0:22:55.5] SS: Thank you.
[END OF INTERVIEW]
[0:22:56.4] MN: Follow us now on Twitter @radiofreerabbit so we can keep the conversation going. Like what you hear? Give us a five star review and help developers like you find their way into The Rabbit Hole and never miss an episode, subscribe now however you listen to your favorite podcast. On behalf of our producer extraordinaire, William Jeffries and my amazing co-host, Dave Anderson and me, your host, Michael Nunez, thanks for listening to The Rabbit Hole.
Links and Resources:
The Pragmatic Programmer on Amazon
Domain-Driven Design on Amazon
Our seasoned cross-functional agilists work with you to develop technology, ship product and deliver value. We leverage our diverse expertise across industries and throughout the organizational growth cycle to your benefit. We bring best practices, emergent practices and creative solutions to your problems.