Two Anti-Patterns To Avoid


Summary

In this episode of Developer Tea, host Jonathan Cottrell explores two software development anti-patterns that developers should avoid. He begins by explaining what anti-patterns are—common problems in code that have established names and refactoring solutions—and categorizes them into those we’re aware of and those we’re not.

The first anti-pattern discussed is dead code, also known as lava flow code. This refers to code that remains in an application but isn’t actually needed or used. Cottrell explains that dead code can include unused database columns, commented-out code, redundant methods with numbered suffixes, and unnecessary dependencies. The problem isn’t just performance—it’s that dead code creates confusion for developers (including yourself when returning to a project) and makes it difficult to determine what code is actually necessary. He suggests using test-driven development and coverage tools like SimpleCov for Ruby to identify and remove dead code, emphasizing that good refactoring involves deleting old code as much as adding new code.

The second anti-pattern is the dead end component, which occurs when developers modify external software they depend on (like WordPress themes, plugins, or open-source packages). By modifying the source code directly, developers create a “dead end” where they can no longer easily receive updates from the original maintainer. This means missing out on security patches, bug fixes, and new features, and taking on full responsibility for maintaining that modified component. Cottrell recommends contributing fixes back to open-source projects instead of creating private modifications to stay in the “future loop” of updates.

Throughout the episode, Cottrell emphasizes that while dead code is somewhat intuitive (like not cleaning your house), dead end components are less obvious but equally problematic. He encourages developers to be vigilant about cleaning up unused code and dependencies, and to avoid modifying external components in ways that create maintenance burdens.

The episode concludes with a recap of both anti-patterns and a reminder that discussions about design patterns and anti-patterns are ongoing in software development.


Recommendations

Services

  • Linode — A cloud hosting provider offering SSD servers with Linux root access, starting at 20 credit with code developertea20.

Tools

  • SimpleCov — A code coverage analysis tool for Ruby that helps identify which parts of your codebase are being exercised by tests, which can help uncover dead code.

Topic Timeline

  • 00:00:00Introduction to anti-patterns in software development — Jonathan Cottrell introduces the concept of anti-patterns—common problems in code that have names and established refactoring solutions. He explains that anti-patterns exist because developers think similarly, and categorizes them into known patterns (things we’re aware of) and unknown patterns (things we don’t realize are problems until they cause issues).
  • 00:02:42First anti-pattern: Dead code and its various forms — Cottrell introduces the first anti-pattern: dead code (also called lava flow code). He describes different types of dead code, including unused database columns, commented-out code, redundant methods with numbered suffixes, and unnecessary dependencies. The core problem is that dead code creates confusion for developers trying to understand what code is actually needed, especially when returning to a project after time away.
  • 00:07:59Strategies for avoiding and removing dead code — Cottrell discusses practical approaches to combat dead code. He suggests using test-driven development and coverage tools (like SimpleCov for Ruby) to identify unused code. However, he notes that coverage tools can’t identify unused tests themselves. The key recommendation is to develop a habit of deleting old code during refactoring rather than just commenting it out or leaving it in place.
  • 00:11:54Second anti-pattern: Dead end components — The second anti-pattern is introduced: dead end components. This occurs when developers modify external software they depend on (like WordPress themes or open-source packages). By modifying the source code directly, they create a “dead end” where they can no longer receive updates from the original maintainer. This means missing security patches, bug fixes, and new features while taking on full maintenance responsibility.
  • 00:17:40Recap and conclusion of both anti-patterns — Cottrell recaps both anti-patterns: dead code (unused code that creates confusion) and dead end components (modifying external dependencies creates maintenance burdens). He emphasizes that while dead code is somewhat intuitive, dead end components are less obvious but equally problematic. The episode concludes with encouragement to clean up code and contribute fixes back to open-source projects rather than creating private modifications.

Episode Info

  • Podcast: Developer Tea
  • Author: Jonathan Cutrell
  • Category: Technology Business Careers Society & Culture
  • Published: 2016-12-07T10:00:00Z
  • Duration: 00:18:55

References


Podcast Info


Transcript

[00:00:00] Hey, everyone, and welcome to developer team. My name is Jonathan Cottrell. And in today’s episode, we are talking about two anti patterns that you should be avoiding in your code. We’ve talked about anti patterns on the show before. But to refresh your memory, an anti pattern is a problem that will show up in your code. And it’s something that has shown up in other people’s code before you. In fact, it’s so common that they have names, they have common ways of being

[00:00:29] refactored. These are things that happened to people before you. And part of the reason this happens, part of the reason anti patterns become a thing is because our brains tend to work similarly. And we tend to have similar behaviors as other human beings, right? So other developers, they think similarly to you. And therefore, they will act similarly to you. A little bonus tidbit aside from today’s planned episode show notes, bonus

[00:00:59] tidbit, there are two basic types of anti patterns, right? There’s two basic types, and perhaps more specifically, two types of anti patterns. Based on your awareness, there are anti patterns that you are aware of, or that you know, you should be doing something intuitively, you know, you should be doing something different, right? And then there are others that are, that are difficult to determine that they are even occurring. In other words, you don’t even know they are happening in

[00:01:29] until they become a problem. Now, this is a really interesting part of learning how to develop software is learning new ways of thinking that are not intuitive, right? The first side of this is that, yes, you know, for example, that having good test coverage or having some kind of verification intuitively, you know, that that is important. But it may not be intuitive to your brain to think that you should have a bunch of

[00:01:59] small files, rather than one large file. That’s not really intuitive. That’s not really something that your brain automatically figures out. It’s something that you figure out with time and with a lot of other people who are developing software learning what helps them develop software better. So think about anti patterns on that scale. There are things that you are aware of these known knowns or even known unknowns. And then there are things that

[00:02:29] that you are not aware of. Unknown unknowns and unknown knowns. And we’ve talked about that

[00:02:36] concept before, but let’s keep that in mind as we talk about these two anti-patterns today.

[00:02:42] Our two patterns, they both have the word dead in them. Perhaps this episode would have been good

[00:02:48] around Halloween. The first pattern that we’re going to talk about today is dead code. Dead code.

[00:02:54] This is also called lava flow code. And dead code is quite simply what it sounds like. It’s code

[00:03:01] that has been left in your application. Now, there are many types of dead code. There’s dead code

[00:03:07] that is still actually being run, but isn’t really having an effect on the system. For example,

[00:03:16] you may have a column in your database where you are storing some information, or perhaps it’s

[00:03:23] working as a cache.

[00:03:24] But that column is never actually used anywhere in your application. Now, there are some reasons

[00:03:30] you may want to do this. Perhaps you want to do a data report later on. But a lot of the time,

[00:03:36] we end up leaving things in place as developers that can be removed altogether. And the reason

[00:03:43] this is so important, this is where it becomes an anti-pattern. There’s not much of a problem

[00:03:50] when it comes to performance to have a few extra lines of code running. But if you have

[00:03:54] a lot of code that is either running or is commented out and isn’t documented, that’s the

[00:04:02] important part. If there’s no way to discern the origin of this code, if there’s no way to discern

[00:04:08] why it is in the system or whether or not I can remove it from the system without breaking things,

[00:04:16] well, it becomes a problem, right? It’s very difficult, especially for new developers coming

[00:04:22] into the project.

[00:04:24] And when I say new developers coming into the project, you can think of yourself as a new

[00:04:28] developer if you leave the project for a period of time and then you come back to it. A lot of

[00:04:34] developers have experienced this phenomenon of returning to code that they wrote and wondering

[00:04:40] who in the world wrote that code. If you exit a project and go and work on a different project,

[00:04:46] a lot of that working memory is lost and you end up losing some of the intuition for the project.

[00:04:52] So if you have dead code,

[00:04:54] in your project, it becomes very difficult to discern the origin of that dead code, right? So

[00:05:01] in other words, you may end up having three or four or 10 different classes or 10 different

[00:05:08] methods or 10 different functions that all perform the same basic task. The same basic thing is

[00:05:16] actually going on in that code. But the problem is it was so difficult to determine which one was

[00:05:21] correct for the new developer that they just didn’t know how to do it. So if you have dead code,

[00:05:24] you just decided to write a new one. And dead code is the result of many different behavioral

[00:05:30] patterns. One of those behavioral patterns is just throwing some code in to test something out.

[00:05:36] I’m sure you’ve said that phrase before. I just want to try something out real quick,

[00:05:41] right? And so you try something out and then that code ends up staying in and it makes it

[00:05:46] into production. And then maybe somebody comes along and writes a secondary method.

[00:05:51] If you have methods, for example, that,

[00:05:54] are numbered, if you have a method that is named the same as a different method, but

[00:05:59] it has a number at the end of it to signify that it is somehow different from the other one,

[00:06:04] that may be a signal that you have dead code in your application. Or at the very least,

[00:06:09] things are very confusing, right? Because a number doesn’t tell me much

[00:06:13] as a new developer about which one of those methods I should be using.

[00:06:18] Another example of dead code, perhaps a little bit less egregious, a little bit

[00:06:23] less dangerous, but it’s a very confusing method. So if you have a method that is named the same as a different method,

[00:06:24] certainly could cause a lot of problems when it comes to performance, is dependencies.

[00:06:32] If you’re loading a lot of extra dependencies, for example,

[00:06:36] if you have a bunch of gems in your gem file, if you’re working with Rails,

[00:06:40] you have a bunch of gems that are never actually being used. You aren’t using any of those packages.

[00:06:45] This happens when you have multiple packages, multiple software packages that do

[00:06:50] essentially the same things. Maybe you have multiple authentications.

[00:06:54] packages or you have multiple json parsing packages whatever it is that you are depending

[00:07:00] on in your application and a lot of the time what happens is that we will add these dependencies

[00:07:05] we’ll start using them in our code then we’ll decide that we want to try a different dependency

[00:07:11] so we’ll add that dependency as well the problem occurs when you don’t remove the previous

[00:07:17] dependency so then you have a long list of dependencies and sometimes hopefully not very

[00:07:24] often but sometimes if you have two or three different packages that that have similar jobs

[00:07:30] they have similar purposes sometimes those will even have name collisions in your in your different

[00:07:38] various name spaces so especially for example if you have a a particular brand and they have

[00:07:44] released multiple versions of let’s say an sdn

[00:07:47] you could possibly have name collisions there as well so there’s a lot of good reasons

[00:07:52] for cleaning up your dependency management as well so how can you avoid having a bunch of dead

[00:07:59] code in your system well we’ve talked about test-driven development quite a bit on developer

[00:08:06] t in the past and despite how you may be doing test-driven development there are ways that you

[00:08:13] can use test-driven development to help you remove

[00:08:16] dead code in your system so if you have a bunch of dead code in your system and you

[00:08:17] have a bunch of old dead code specifically take a look in whatever language you are using

[00:08:21] at coverage detection options for example for ruby there’s simple cov and what that does is

[00:08:29] it allows you to determine how much of your code base has been covered now what you will find out

[00:08:36] is that if you start replacing some of that old dead code or if you stop using some of the old

[00:08:41] dead code then you will actually see that that percentage is going to be

[00:08:47] lower right because a lot of the code that you were using before is not actually even getting hit

[00:08:52] in your tests now what this can’t do is it cannot determine which of your tests is no longer needed

[00:08:59] so you may have tests and coverage uh you may have actual code and coverage in your tests for

[00:09:07] that code and it could be old and dead and not actually needed in your application so that’s

[00:09:13] something that you’re going to have to stay on top of yourself now how does that work for you

[00:09:17] how does that work well a lot of the time what we will end up doing in our coding practice we will

[00:09:23] go through and add new things and instead of removing the old thing we either comment it out

[00:09:28] or we just leave it in place right and that is the practice that has to stop a good refactoring

[00:09:34] process it includes changing and deleting the old code that you’re refactoring so building an

[00:09:42] application is almost as much changing existing code as changing the old code that you’re refactoring

[00:09:47] as it is adding new code and hopefully there’s quite a bit of deleting code as well so be

[00:09:54] vigilant about this it’s very important that you stay on top of deleting old unused code

[00:10:00] deleting old unused parts of your databases deleting dependencies you no longer use and

[00:10:06] deleting tests that you no longer need that’s the first anti-pattern that i want to talk to

[00:10:12] you about today we’re going to talk about our sponsor real quick and then we’re going to talk

[00:10:15] about the second anti-pattern

[00:10:17] today’s episode is sponsored by linode with linode you can get an ssd server up and running

[00:10:24] in just a few minutes now some of you may not know this a good portion of what developer t does

[00:10:31] actually relies on linode a lot of our hosting services actually run through linode so it works

[00:10:37] at scale but it also works for those of you who are just getting started in development there’s

[00:10:42] quite a few beginners who listen to the show and it’s never too early

[00:10:47] to get started with a server you know a lot of the skills that you will gain by getting a server up

[00:10:53] and running they will stick with you throughout your coding career and it’s just a lot of fun to

[00:10:59] have a server honestly to build something and put it up on the internet or make it accessible in a

[00:11:05] remote location it’s a ton of fun on top of that of course you get root access to these servers

[00:11:11] they’re built on linux i’m sure you’ve heard of it but if you haven’t obviously linux is running

[00:11:17] all of the web so go and check out linode they have incredible plans incredible pricing ten

[00:11:23] dollars a month is their starting point and that gets you two gigabytes of ram on on a server so

[00:11:29] go and check that out spec.fm slash linode oh and by the way they’re giving you twenty dollars of

[00:11:34] credit if you use the code developer t20 at checkout that’s twenty dollars of credit that’s

[00:11:39] basically two months on that entry-level plan so go and check it out spec.fm slash linode thank

[00:11:45] you again to linode for sponsoring today’s episode of linode i’ll see you next time bye bye

[00:11:47] developer t the first anti-pattern that we’ve already talked about is dead code the second

[00:11:54] anti-pattern that i want to talk to you about is called dead end dead end more specifically we’re

[00:12:01] talking about the dead end component and hopefully you’ve experienced this before if you have you will

[00:12:07] immediately recognize this anti-pattern it is not necessarily intuitive right we talked about this

[00:12:15] earlier that some anti-patterns are not intuitive and some anti-patterns are not intuitive and some

[00:12:17] patterns are are somewhat intuitive having dead code in your application it kind of feels like

[00:12:22] you haven’t cleaned up your house right it feels a little bit dirty it feels like you need to

[00:12:29] straighten things i’m cleaning things up get some stuff out of the way so that one’s a little bit

[00:12:33] more intuitive the dead end component though that’s actually a less intuitive anti-pattern

[00:12:40] what a dead end component is if you have some software that you are depending on right so let’s

[00:12:46] say you’re using a software that you’re using a software that you’re using a software that you’re

[00:12:47] you work with wordpress and i actually experienced this one recently you work with wordpress and you

[00:12:52] bring in a theme or a plugin from an external developer your client asks you to to install that

[00:13:01] theme but then they want you to bring in a component from a different website or in this

[00:13:08] particular case they wanted us to install a theme for their blog and then bring their nav over from

[00:13:15] their main website

[00:13:17] right so they have a blog theme but they want the nav from their other website

[00:13:21] brought into this theme now the interesting thing about software and depending on other people’s

[00:13:29] software is that you get a lot of value out of depending on other people right open source

[00:13:36] software is incredibly valuable you all know this having plugins that you never had to write all you

[00:13:42] had to do was click install that is a lot of value with the software that you’re using right now so

[00:13:47] before i was doing any of these other things with very little effort now the trade-off is that that

[00:13:51] software is not always going to be exactly what you need right now this is a very common problem

[00:13:58] in business when you have a non-custom solution the things that are specific to your problem

[00:14:05] may or may not be fully addressed this is the concept of off the shelf versus customized

[00:14:13] software for example so that is a problem that you’re going to face

[00:14:17] Now, what happens, the dead-end pattern, what happens is when you choose to modify those

[00:14:23] things that you were depending on, so if you added that nav to that theme in the WordPress

[00:14:29] install, or if you go through and you patch different pieces of code, especially if you

[00:14:35] modify the actual source rather than laying monkey patching on top, for example, even

[00:14:42] that can go wrong, but if you’re modifying the source that you’re depending on, then

[00:14:47] you are creating a dead-end.

[00:14:50] Now, what does that mean?

[00:14:51] Well, most of the time, the software that you depend on will receive updates in the

[00:14:56] future, whether that’s stability updates, maybe it’s compatibility updates, maybe it’s

[00:15:02] safety upgrades, or it could actually be brand new features.

[00:15:07] It could be newer, better, faster things that the original developer, that software,

[00:15:12] decided to add to that software.

[00:15:15] Now, the problem is, if you have modified, let’s say you’re on version 2, if you modified

[00:15:21] version 2 and they come out with version 2.1, the problem is that whatever their changes

[00:15:27] are, they could overwrite your changes.

[00:15:30] In other words, your changes are not necessarily going to be easily merged with the original

[00:15:36] developer’s changes.

[00:15:38] So, in this way, you’ve created a dead-end because you no longer get to…

[00:15:42] to see the benefits of that ongoing development of that software.

[00:15:48] Now, perhaps what’s even worse about a dead-end component is that all of the responsibility

[00:15:53] is now entirely yours.

[00:15:57] Think about that for a second.

[00:15:58] If you go through and you modify a plugin or you modify some kind of package that you’ve

[00:16:04] brought into your project, if you go through and modify it and you create a dead-end where

[00:16:09] the original software maintainer…

[00:16:11] no longer can add changes to that, right?

[00:16:15] You can no longer bring down their changes and add them to that project.

[00:16:18] It is now your responsibility to implement those safety upgrades, those security and

[00:16:25] performance upgrades, those feature additions.

[00:16:28] And again, this doesn’t necessarily immediately click with our brains.

[00:16:33] When we see something wrong, we think, oh, we can fix that.

[00:16:37] We know exactly what’s wrong in that piece of code.

[00:16:39] Again, the problem with this…

[00:16:41] is that once you go in and modify that underlying structure, you’ve now created your own branch

[00:16:48] of that software effectively, right?

[00:16:50] And if the original developer doesn’t have access to that branch, they can no longer

[00:16:55] continue developing on that piece of software.

[00:16:59] This is why it’s so important to take those changes that you’ve made, especially if they

[00:17:05] are, you know, globalized things.

[00:17:07] For example, if you find a bug in some software that you depend on, then you can…

[00:17:11] take that bug, take the fix that you’ve applied, and contribute to that project, if it’s an

[00:17:18] open source project, or send the information to the original developer.

[00:17:22] This allows you to stay in that future loop, right?

[00:17:26] In other words, you aren’t creating a dead end when you bring your changes into the open

[00:17:32] source sphere.

[00:17:34] So a quick recap are two anti-patterns for today, dead code and dead end.

[00:17:40] Dead code is…

[00:17:41] code that is unused, whether it’s commented out, or it is simply just sitting in your

[00:17:47] code base, it’s being run, but it’s never actually needed.

[00:17:50] Dead end is when you take a component that you are relying on in your application, that

[00:17:56] is built by an external developer, someone else, whether that’s open source or not, and

[00:18:01] you modify that underlying code.

[00:18:03] This creates a dead end in your code because you can no longer take new updates to that

[00:18:09] underlying component and apply them.

[00:18:12] Thank you so much for listening to today’s episode of Developer Tea.

[00:18:15] I hope you’ve enjoyed this discussion on anti-patterns.

[00:18:18] Of course, anti-patterns and design patterns for software is a never-ending discussion,

[00:18:25] and we will continue talking about this in the future on Developer Tea.

[00:18:29] If you want a server in the cloud, if you want an SSD server in the cloud with two gigabytes

[00:18:34] of RAM, and you want 20 bucks for free, go and check out spec.fm slash linode.

[00:18:39] Remember the code developertea20 at checkout.

[00:18:41] And you’ll get that $20 worth of credit.

[00:18:44] Thank you again for listening to today’s episode.

[00:18:46] Until next time, enjoy your tea.