Arjan correctly argues that dogmatic adherence to DRY often creates more complexity than it solves through tight coupling. This is a necessary reminder that code maintainability depends on separating responsibilities, not just eliminating repetition.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
DRY Often Makes Your Code WorseAdded:
Here's some example code for normalizing email addresses and usernames. Uh there's two functions here that do that job. And I have a main function that has a bunch of email addresses and users and then normalizes them. When I run this, then this is what we get. Now obviously this code has quite a bit of duplication, right? If you take a look at these function bodies. So naturally we should apply dry. Don't repeat yourself and remove it. Let's do that.
So, first I'm going to create a new function called normalize strings and this is going to get a list of items and it will return a list of strings.
Now, we just need to pass in the various options that control how these strings are being normalized. So, should there be an at symbol? Is there a minimum length of the string? and a couple of other things as well that we can all see from these two functions. So let me paste that in here like so. So these are all the options that we have. Then inside the function we can create the result which will be a list of strings.
Initially that will be empty and in the end this is what we're going to return.
And then we can go over the items in the list of items.
And then for example, if strip white space, we're going to strip the item and if lowerase, we're going to turn it into lower case.
And similarly, we can go through all of these different options and do whatever we need to do in order to take care of those. Finally, we're going to append the item to the result and then we can return it.
And now that we removed all of this nasty duplication, we can now replace these calls with our new function. So instead of calling normalize email addresses, we can call normalize strings.
And then we just need to pass the email addresses.
So for an email address the require at symbol needs to be there. We also want to split the at symbol and we want to strip the mail prefix and that gives us our normalized emails. And then I can do the same thing for usernames. So also here normalized strings and then I pass the usernames.
The minimum length should be uh three.
There we go.
And the we also want to remove the add prefix like so. And now when I run this code again, we get exactly the same result. So what happened here? There's less duplication for sure. I removed most of it, but the code has become way worse. The behavior currently is impossible to understand. There is all sorts of flags that interact in non-obvious ways. uh every new requirement now means that we need to add another parameter to this very generic function that doesn't repeat itself. So I may have removed duplication but I also turned the code into a hot mess. So what actually happened here? Now before I show you what is actually the right way to refactor this, what I've learned over the years is that it's not just important that you know how software design principles and patterns work.
It's also important that you understand the trade-offs that are behind them. And that's exactly what I go deep into in software design mastery. This is not just another course with patterns and principles. It's a comprehensive system for thinking about architecture, boundaries, tradeoffs, long-term maintainability. If you want to become truly confident in your design decisions, join the waiting list atodes/mastery.
The link is also in the video description. So, what does this teach us about dry? But don't repeat yourself doesn't mean that you should merge anything that looks similar into a one function. It's it's actually more about not duplicating knowledge. And knowledge in code is in things like data, rules, business logic, those kind of things.
Now in the bad refactor that I just did, I purely focused on how the code was shaped. I looked at if statements, for loops, and things like that, and then try to remove all of that duplication.
If you want to improve code, don't just blindly apply a principle like try. You actually need to understand the code.
So, let's try this again, but now let's focus on behavior and responsibilities.
So, I just threw out the bad refactor that I did and I went back to the original code. So, this is again what it looks like. Let's analyze what is happening here. So first thing is that these normalized functions they actually do two things. One which is uh filtering. For example here if there is not an at in address it's simply not going to consider it. Uh but uh we see the same thing happening in the username. So there is filtering and there's normalization. Now if we don't focus too much on trying to remove all the duplication, we can actually start splitting out this logic more which is what makes way more sense when you want to improve the code. For example, for the filtering bit, we can use another function to check whether an email address is actually valid.
So let's say we have function is valid email. It's got some address and this is going to give us a boolean value that determines whether this address is actually valid and that is actually where we can use this check. So here we're going to return that there is actually an at sign in the address and then now we can write it like this.
So now we moved some of the logic and this is still pretty simple but we moved some of the logic outside of the function which is nice and we can do the same thing for the usernames.
So here the length of the username should be more or equal than three like so.
But now that we've split out this logic, we can take a look at for example this function and see if we can focus the responsibility a bit more. Because currently this is responsible for checking that an email address is valid by calling this function. It's responsible for looping through a list of addresses and then actually doing the normalization process. So those are actually way too many responsibilities.
So let's split up the responsibilities.
And again, I'm not thinking about duplication at this moment. I'm truly just thinking about how to organize this code better. And if I have to write a few extra lines of code for that, I don't really care about it. So instead of having this function that normalizes all the email address in the list and also checks whether emails are valid, let's create another function called normalize email address that does basically the normalization job for a single email address.
This normalize the address and we'll return that as a string value. So then we can basically take this part like so and I'll put it in here and then we can refactor that. So this actually should not be part of email address normalization.
So the first step is removing whites space and turning it into a lower case.
Then we get the local part and the domain. We remove the prefix from the domain and then we're simply going to return this as a result. So this is our normalize email address function. And now actually normalize email addresses can be very simple uh because we don't need all of this complication here. We can even make this a lot shorter and just use a list comprehension.
There we check if the email address is valid.
So now we turn this complicated function into something that's way simpler. And for usernames we can do the same thing.
So here I'm also simply copying this putting it in here. We don't need the valid check here.
And I can simply return this as a result. and I don't need to store it here. And then also here in normalize usernames, I can simply use a list comprehension like so. Let's run this to check whether this still works as expected. Now, when you take a look at this version of the code, actually, I didn't remove all the duplication because that wasn't the focus. I didn't focus on trying to remove duplication. And actually, there is still duplication in here, like normalizing email addresses. Well, this code looks a lot like normalizing the usernames except it calls slightly different functions. Now you could decide to abstract that away and make like a filter and process function or something like that if you really wanted to but honestly to me this isn't that bad that there is some duplication.
However, I did remove the right duplication in the sense that validation rules like these kind of checks are now in a single place and normalization rules are also in a single place because they're grouped in these functions now.
they're not all mixed up. And by doing this, it means that our control flow stays simple and still readable even though there is still some duplication.
And actually, in many cases, having some duplication in code is good. These loops or list comprehensions, I don't really mind that they're duplicated. It's they're pretty cheap. It's not many lines of code. It's easy to read. But more importantly, duplication can sometimes help you enforce boundaries.
For example, you may also encounter duplications sometimes in your API, right? You might have a database schema, you might have an API output schema, and these are going to be very similar. So, you might be tempted to use the same object for that. Maybe if you're using SQL model or something, but that couples your API directly to your database, your persistent layer. By keeping them separate, you avoid leaking database concerns into your API and it gives you flexibility to evolve each of these independently. So there is some duplication in that case there. But repeating yourself is actually protecting your design in that case. So overall when you're working on code like this, I'd say prefer duplication over the wrong way of abstracting things.
Look for uh duplicated rules, not duplicated loops, and try to fix those.
If you notice that you need to add a bunch of flags in order to remove the duplication from the code, that's probably a red flag, pun intended. So instead, focus on truly understanding the code. You'll be way better at organizing the code more effectively.
And what I typically do when I write code, whether that's me or some AI coding agent, is that I start writing, I don't really think about how it looks. I copy things around when I need them. But when I notice that there is actually duplicated rules, then I might abstract things away. So abstraction is a consequence of writing the code and copying things around. I don't start there. When using a tool like cloud code, you can just let it write all the code, but then you do need to take that step of understanding the code that it wrote and seeing if you can abstract away a couple of things. And by the way, if you enjoy these types of design videos, get video like, subscribe to the channel. It helps me reach more people here on YouTube. So, finally, dry don't repeat yourself is not a wrong principle, but it's really easy to misuse. It's easy to think that you should somehow not have any duplication in the logic. That's not what it means.
The key thing is that you understand the code and that you abstract away the right things so that they're properly separated and that knowledge, data, business logic is not duplicated in your code. If you do it blindly, just start refactoring and moving things around, you'll often end up in a worse place.
You need to understand it and that leads to better abstractions. But I'd like to hear what you think. Do you apply the dry principle yourself to code? Do you tend to overabstract things or do you tend to keep duplication around much longer? Have you ever tried to refactor something removing duplication and it completely backfires? Let me know in the comments. Now, if you want to explore more software design videos, check out my design patterns playlist right here.
Thanks for watching and see you next
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 viewsโข2026-05-28
How agent o11y differs from traditional o11y โ Phil Hetzel, Braintrust
aiDotEngineer
450 viewsโข2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation๐ฏโ
LearnwithSahera
1K viewsโข2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 viewsโข2026-05-29
Search Algorithms Explained in 60 Seconds! ๐ค๐จ
samarthtuliofficial
218 viewsโข2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 viewsโข2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 viewsโข2026-05-29
So What's Odin Lang Even Good For
TechOverTea
131 viewsโข2026-06-01











