Refactoring Based on Code Responsibility
Summary
In this episode of Developer Tea, host Jonathan Cottrell explores the critical importance of clearly defined code responsibility for maintainability. He frames the discussion around four specific situations where code responsibility becomes difficult to determine, drawing from a recent personal experience with confusing JavaScript code.
Cottrell first addresses poor naming practices as a fundamental problem. He emphasizes that code serves dual purposes: processing data and communicating with developers. Using descriptive names for variables, functions, and classes is essential because it guides future developers (including your future self) through the code’s intent. He strongly advises against one-letter variable names, noting that the minimal overhead of longer, descriptive names provides tremendous value in clarity.
The second issue discussed is ‘tag-along code’—when developers hastily add unrelated functionality to existing functions rather than creating properly named, separate functions. This practice invalidates the original function’s name and creates confusion about responsibilities. Cottrell recommends always creating new, appropriately named functions for distinct responsibilities to avoid this mixing of concerns.
Third, Cottrell examines ‘container functions’ or ‘God objects’—overly powerful models or initialization methods that accumulate too many responsibilities. These become unpredictable, difficult to test, and resemble unorganized imperative code. The solution is to extract individual routines into separate, well-named functions, allowing container functions to serve as readable checklists rather than monolithic blocks of logic.
Finally, he discusses mixing presentation with logic, a longstanding but increasingly relevant concern with modern libraries like React. While not requiring separate files, Cottrell stresses that logical methods should be agnostic to presentation details. Creating separate methods for logic and presentation, with logic methods unconcerned with how their output is displayed, dramatically improves code maintainability and represents a powerful conceptual shift in development approach.
Recommendations
Tools
- FreshBooks — Online accounting software for creative entrepreneurs that helps with invoicing, expense tracking, time tracking, and automatic late payment reminders. The host mentions they’re offering Developer Tea listeners a free month.
Topic Timeline
- 00:00:00 — Introduction to refactoring and code responsibility — Jonathan Cottrell introduces the episode’s focus on refactoring tips for determining code responsibility. He explains the importance of clear responsibility for new developers joining a project and shares that the episode was inspired by a recent work experience where code responsibility was unclear. The introduction frames the discussion around four specific situations where code responsibility becomes difficult to determine.
- 00:02:23 — First problem: Poor variable, function, and class naming — Cottrell identifies poor naming as the first major issue that obscures code responsibility. He explains that code communicates both with the computer and with developers, making proper labels essential. He advises against one-letter variable names, arguing that descriptive names provide far more value than the minimal overhead they create. The segment emphasizes that good naming guides future developers and helps even the original author when returning to code years later.
- 00:07:04 — Second problem: Tag-along code in functions — The host introduces ‘tag-along code’ as the second pitfall—when developers add unrelated functionality to existing functions instead of creating new ones. He illustrates this with a JavaScript example where a function creating HTML later gets modified to also add a class to a header. This practice invalidates the function’s original name and mixes responsibilities. Cottrell’s solution is to extract unrelated code into new, properly named functions or methods.
- 00:09:15 — Sponsor message: FreshBooks accounting software — Cottrell thanks FreshBooks for sponsoring the episode and details their services for creative entrepreneurs. He explains how FreshBooks helps users get organized, save time, and get paid faster through online invoicing, automatic late payment reminders, receipt organization via mobile app, expense importing, and time tracking. He directs listeners to claim a free month by visiting freshbooks.com/developertea and entering ‘developer tea’ during sign-up.
- 00:13:56 — Third problem: Container functions and God objects — Cottrell discusses ‘container functions’ or ‘God objects’ as the third issue—overly powerful models or initialization methods that accumulate too many responsibilities. He uses WordPress initialization functions as an example, noting they become unpredictable, difficult to test, and resemble unorganized imperative code. The recommended approach is to extract individual routines into separate functions, allowing container functions to serve as readable checklists rather than monolithic logic blocks.
- 00:17:11 — Fourth problem: Mixing presentation with logic — The final issue addressed is mixing presentation with logic, a longstanding concern made more relevant by modern libraries like React. Cottrell clarifies that separation doesn’t necessarily require different files, but rather that logical methods should be agnostic to how presentation methods use their output. He emphasizes creating two distinct methods—one for logic, one for presentation—with the logic method unconcerned with presentation details, calling this an incredibly powerful concept for maintainability.
- 00:19:29 — Closing remarks and announcements — Cottrell thanks listeners and announces that Developer Tea has just launched on Google Play for Android users. He reminds listeners about the FreshBooks sponsorship offer and encourages leaving reviews on iTunes to help other developers find the podcast. The episode concludes with a reminder to check show notes at spec.fm for all mentioned links and details.
Episode Info
- Podcast: Developer Tea
- Author: Jonathan Cutrell
- Category: Technology Business Careers Society & Culture
- Published: 2016-04-20T07:00:00Z
- Duration: 00:21:50
References
- URL PocketCasts: https://podcast-api.pocketcasts.com/podcast/full/cbe9b6c0-7da4-0132-e6ef-5f4c86fd3263/e63376b3-f8f0-45a0-b14d-38935997dd43
- Episode UUID: e63376b3-f8f0-45a0-b14d-38935997dd43
Podcast Info
- Name: Developer Tea
- Type: episodic
- Site: http://www.developertea.com
- UUID: cbe9b6c0-7da4-0132-e6ef-5f4c86fd3263
Transcript
[00:00:00] Welcome to Developer Tea. My name is Jonathan Cottrell, and in today’s episode, I’m going
[00:00:08] to be talking to you about refactoring tips. Specifically, we’re going to be talking about
[00:00:13] refactoring tips for determining responsibility. Today’s episode is sponsored by FreshBooks.
[00:00:21] FreshBooks is the ridiculously easy to use online accounting software designed to help
[00:00:27] creative entrepreneurs get organized, save time, and get paid faster. We will talk more
[00:00:33] about what FreshBooks has to offer to Developer Tea listeners later on in today’s episode.
[00:00:39] But first, I want to talk about these refactoring tips. And we’re going to frame this through
[00:00:44] the lens of different places where responsibility of code can go haywire. Code should call out
[00:00:53] what it is responsible for.
[00:00:56] And I have four times.
[00:00:57] When the responsibility of code can be basically impossible to determine or incredibly difficult
[00:01:04] to determine. And really, here’s why it’s important. If a new developer comes to the
[00:01:09] project, right? Let’s say the developer has never seen the code for that particular project,
[00:01:15] and they come to the project and they realize that they need to work on this one particular
[00:01:20] piece of code, but it’s impossible to determine what pieces are doing what.
[00:01:27] Now, this is a very important piece of code. It’s a very important piece of code. It’s a
[00:01:27] This episode is certainly inspired by a recent example at my work. I was working on some
[00:01:33] code and it was difficult to determine exactly what that code was doing. And I couldn’t determine
[00:01:39] what was responsible for what was happening in the interface. I was working on some JavaScript.
[00:01:45] And so I want to point out a few things that can fix this problem before it occurs in your
[00:01:52] code. This is a huge maintainability issue. Because if I come to the code, I’m going to
[00:01:57] as a new developer, and I don’t know what that code is responsible for, I could introduce brand
[00:02:03] new bugs that you never necessarily saw coming because that code may be responsible for something
[00:02:10] that’s totally outside of the context of where that code shows up. So let’s talk about these
[00:02:16] four times when code can go haywire, when the responsibility of your code can go haywire.
[00:02:23] And the first one, this shouldn’t surprise you, is poor,
[00:02:27] variable naming. And when I say variable, I mean, poor function naming, poor class naming,
[00:02:34] poor variable naming, of course, poor constant, anything that you name as the developer,
[00:02:41] your responsibility is incredibly high here. Incredibly high. There is a huge amount of talent
[00:02:48] that is necessary to be able to name things properly. Now we’ve talked about naming being
[00:02:54] a difficult problem on the show.
[00:02:57] And it can’t be stated enough. Learning how to label things well is absolutely essential to
[00:03:03] writing good, maintainable code. You can’t write good code without proper labels. Code is really
[00:03:10] doing two things, right? This is why labels are important. Code is really doing two things. It’s
[00:03:17] processing something, whether that is input, maybe it’s some data that exists elsewhere. Maybe it is
[00:03:24] just time, for example.
[00:03:27] There’s something that it’s processing, right? It’s doing something. And it’s explaining to the
[00:03:33] developer how that processing is occurring, okay? So it’s a two-way communication. It’s
[00:03:39] communicating with the computer, and it’s communicating with a user, in this case,
[00:03:44] the developer. Of course, code can do more than that. For example, it can model behavior
[00:03:49] and characteristics. But ultimately, what code does is it creates some set of pathways or actions
[00:03:57] and it provides a way for humans to read and manipulate those pathways. So when we talk about
[00:04:03] responsibility, it’s incredibly important to name things well so that the responsibility of that
[00:04:09] particular reference, that particular object, is determined easily by someone new coming into the
[00:04:16] project. If you labeled something one-letter variable name, for example, this is a really
[00:04:21] common thing that you’ll see. And a practical tip for those of you who are writing code,
[00:04:27] you’re looking for a very simple practical tip, stop using one-letter variable names. And the
[00:04:32] reason is, it’s kind of difficult to know what that one letter is actually implying, what it
[00:04:37] refers to. We see these all the time when we look at generic algorithms. And that’s probably the
[00:04:44] reason why we use them in our code. We may also think that it makes our code a little bit smaller
[00:04:49] and therefore a little bit more efficient. And this is true to a certain extent, but not to a
[00:04:55] reasonable extent.
[00:04:57] In other words, you’re going to get much more out of naming your variable a few letters longer,
[00:05:03] just a few bytes more. You’re going to get so much more value out of that than you gain by keeping
[00:05:10] your variable names short. So go ahead and name it something significantly more descriptive.
[00:05:17] Most of the time, any of the issues that you would have experienced as a result of that name being
[00:05:23] too long will be resolved by either a
[00:05:26] compiler or a
[00:05:27] compressor or a minifier. It typically is going to be resolved. And most of the time, it’s not even
[00:05:34] that much of an overhead anyway. So go ahead and name your things much more descriptively. But
[00:05:40] imagine that you come into a project and you have something that is named really broadly or
[00:05:46] really non-descriptively. Well, how do you find out what that thing is doing? You have to go in
[00:05:52] and read every single line of code and determine, okay, what is this?
[00:05:57] What is this particular function, this foo function that I’m seeing? What is it actually performing?
[00:06:02] What are the effects? What are the side effects? What are the inputs and outputs? What should I
[00:06:07] expect from this code? And you as the programmer, you have the opportunity to point programmers in
[00:06:15] the future in the right direction if you name things well. Okay, don’t miss this. You have the
[00:06:23] opportunity as a developer to point future developers,
[00:06:27] that includes you, by the way. If you come back to the project after a few years, I promise you,
[00:06:31] you’re not going to remember what that abstractly named function is supposedly doing. You have the
[00:06:38] opportunity to point those developers in the right direction if you simply name things well.
[00:06:45] Okay, so that’s number one. Number one, poor variable naming can cause a massive problem in
[00:06:51] your code. Name things well, and you can help your future self, other developers, you can help
[00:06:57] them in the right direction. And if you come back to the project after a few years, I promise you,
[00:06:57] out significantly. Number two is what I like to call tag-along code. Tag-along code. Go open a
[00:07:04] piece of code you wrote in a hurry, and you’re likely to see this poor practice. You have a
[00:07:11] really well-written function that runs, and it does a few things. Maybe, let’s say you’re writing
[00:07:16] JavaScript, and it creates some HTML to inject into your page, and everything is looking great.
[00:07:23] But then you need to add one little unrelated thing to
[00:07:27] the page. Now, you could go and create another function, and create tests for that function,
[00:07:32] and you could rename everything, and go through that whole process. Or in your hurry,
[00:07:37] what is more likely is that you added that little bit of code to the end of that function. You’ve
[00:07:43] tagged it on as if it was a part of that function. Now, the problem with this is related to the first
[00:07:50] issue. And that is, even if your function is well-named, in this scenario, you’re doing something
[00:07:55] that doesn’t necessarily work. So, if you’re doing something that doesn’t necessarily work,
[00:07:57] it doesn’t necessarily fit inside of whatever that function was initially intended to do.
[00:08:02] So, now you’ve created basically the same problem that you had in the first point, which is the name
[00:08:08] suddenly is invalid. You could possibly rename that function foo and bar, whatever foo is and
[00:08:17] whatever bar is. Hopefully, you’re not using those names specifically, but maybe you’re creating HTML.
[00:08:23] So, you could name it create HTML if it was named that,
[00:08:27] initially, and then you added something else like add a class to the header, create HTML and add
[00:08:33] class to header. But now, you run into issues of that code just being terrible to look at,
[00:08:39] and your responsibilities are getting mixed up with each other. This is the problem that tag-along
[00:08:44] code can create. You’re much better off if you go ahead and take that code out of that function
[00:08:50] and create a new function or a method. Whatever you need to do, create a new container with a
[00:08:56] new name for that particular job. Okay, so tips one and two are times when your code will go haywire.
[00:09:03] Number one was when you name things poorly, and number two is when you add tag-along code.
[00:09:10] Now, I have two more for you, but first, I want to talk about today’s sponsor,
[00:09:15] FreshBooks. This is FreshBooks’ first episode of Developer Tea. So, thank you so much, FreshBooks,
[00:09:21] for joining Spec and sponsoring Developer Tea.
[00:09:25] FreshBooks is the
[00:09:26] ridiculously easy-to-use online accounting software designed to help creative entrepreneurs
[00:09:31] get organized, save time, and get paid faster. How do you get paid faster? Well, your clients
[00:09:39] can pay you online. You create your invoice. It literally takes about 30 seconds, and your clients
[00:09:45] can pay you online. This is so much faster than them trying to send you a check or whatever it
[00:09:50] is that your clients normally do. Paying online is just a few clicks away, right? If a client
[00:09:55] forgets to pay you online, they’re not going to be able to pay you back. They’re not going to be
[00:09:56] able to pay you back in time. FreshBooks handles the awkwardness of reminding them. You can send
[00:10:02] customizable late payment reminders automatically through FreshBooks, so you don’t have to give them
[00:10:08] a call and ask them to pay you since they’re late. On top of this, FreshBooks has a mobile app,
[00:10:14] which will let you take pictures of your receipts, and then it organizes them for you to go through
[00:10:20] later. Beyond that, FreshBooks can also automatically import expenses directly from your account. So,
[00:10:26] you have no excuse when you’re tracking expenses anymore. It makes it so easy to just go and get
[00:10:34] those expenses directly, either from the pictures you take of your receipts or directly from your
[00:10:39] bank account. FreshBooks will also handle your time tracking, so when it comes time to create
[00:10:44] that invoice, you’ll know what you did and when you did it. All the little details about cash flow
[00:10:51] are kept in one place, so FreshBooks knows exactly what invoices you sent,
[00:10:55] when you sent them, and when you sent them back. So, you don’t have to worry about the
[00:10:56] who’s paid you, and perhaps most importantly, who owes you what. So, to claim your free month,
[00:11:05] this is what FreshBooks is giving Developer T listeners, a free month on FreshBooks. Go to
[00:11:10] freshbooks.com slash developer T and enter developer T in the how did you hear about us
[00:11:17] section when you sign up. If you’ve been putting off your bookkeeping, this is tax season,
[00:11:23] if you’ve been putting it off, then today is the day.
[00:11:26] to start getting that stuff cleaned up. Go to freshbooks.com slash developer T. Of course,
[00:11:32] that link can be found in the show notes at spec.fm. Thanks again to FreshBooks for sponsoring
[00:11:38] Developer T. Okay, so we’ve been talking about refactoring, and we’re talking about determining
[00:11:44] the responsibility of different parts of your code. And I’m outlining a few times when your
[00:11:50] code may go haywire, where it becomes incredibly difficult to determine the responsibility of a
[00:11:56] particular piece of code. So, if you’re a developer, and you’re a developer, and you’re a developer,
[00:11:56] now, hopefully, this will help you avoid that situation in the future. Because the refactoring
[00:12:02] process, when things are poorly named, for example, is very difficult. You have to go back and forth
[00:12:08] with whatever the product is that front end, and the back end to determine whatever it is that this
[00:12:14] particular method or function is trying to do. It’s really hard, it’s really expensive. And it’s
[00:12:20] much better to just go ahead and avoid it on the front end. So we talked about number one, poor
[00:12:26] variable naming, this is an incredibly huge issue, especially when you’re first starting out, and
[00:12:32] you’re wanting to move through things very quickly, and there’s not a lot of code. It’s easy to name
[00:12:37] things very short variable names when there’s not a lot of code. When the code gets longer, those
[00:12:42] short variable names that you have, you kind of go to that same variable name over and over, that’s
[00:12:47] going to come up over and over in your code. And then it’s going to be hard to discern one function
[00:12:52] from another one method from another. So make sure you’re naming things very short. And if you’re
[00:12:56] naming your stuff properly, this takes just a few extra brain cells, a few more seconds to make
[00:13:02] sure that those names are correct. But it saves you so much time in the long run. Number two was
[00:13:08] tag along code. Even if you get the naming of that particular method or function correct,
[00:13:14] if you add code that doesn’t belong in that method, well, now that name is no longer correct.
[00:13:20] And it’s going to be hard to track down where that code was added. If you’re looking for it in the
[00:13:25] future.
[00:13:26] So make sure you don’t add tag along code into methods where it doesn’t belong. A good rule of
[00:13:31] thumb here is just create a method, create a new function. If you are in doubt, go ahead and create
[00:13:38] a new function. This is so much easier than actually trying to discern where these things
[00:13:44] came from. Why does this method have this thing that’s totally unrelated in it? Just avoid that
[00:13:49] altogether. Create an extra method that gives it a name that gives it something for you to describe
[00:13:54] it by. Okay.
[00:13:56] So that’s number one and two. Number three, container functions, or you might hear this term
[00:14:02] God objects or God classes, God models. And the idea here is the model is too powerful. It has
[00:14:10] too much stuff in it. It has too many methods attached to it. Or for example, an initialization
[00:14:16] method. This happens most often in initialization or cleanup methods, these hooks that we, you know,
[00:14:23] we hook into these things that are happening.
[00:14:25] Maybe in the back end, we’re hooking into them into the front end, or maybe there’s an API for
[00:14:30] this. This happens all the time. For example, in WordPress programming, you have initialization
[00:14:35] functions and cleanup methods, and they collect a bunch of actions into one big string of stuff.
[00:14:43] It’s one big method that just holds all of these actions that are one after the other,
[00:14:48] one operation after the other. And really this isn’t much different than putting those methods
[00:14:54] or those.
[00:14:55] Declarations or those actions at the top level, like you might see in a utility script.
[00:15:02] The reason this is similar is because if you were to just take out the function name,
[00:15:06] the initialization function, which really doesn’t tell you a lot about what’s happening,
[00:15:11] then all you have is a bunch of unorganized imperative code. And this is what we’re trying to
[00:15:17] avoid when we create these functions or when we containerize these ideas into their own methods.
[00:15:24] We’re trying to avoid this top level kind of global dirty space where everything is happening
[00:15:31] in parallel to each other and there’s no particular organization. And that’s what we get
[00:15:37] when we create these initialization functions or cleanup functions or whatever you want to
[00:15:44] call those things. Those things that collect a bunch of different actions into an event.
[00:15:50] And the problem is not only that they have multiple responsibilities, which is,
[00:15:54] of course, already a problem, but they also are very unpredictable. They’re very unpredictable
[00:16:00] and often end up having a bunch of really poor patterns like nested logical branching,
[00:16:06] multiple return statements, side effects all over the code. On top of this, container functions can
[00:16:11] be incredibly difficult to test and just as difficult to document. An acceptable alternative
[00:16:18] is to create functions outside of those container functions that perform the individual root
[00:16:24] routines or actions or the individual pieces of imperative code that end up showing up in the
[00:16:31] initialization. This allows initialization functions to exist because it’s important to have
[00:16:37] these event driven type functions and you read them more like a checklist rather than a long
[00:16:45] detailed imperative routine. Okay, so what you want to do is avoid these container functions,
[00:16:51] avoid these God objects, these things that have
[00:16:53] far too many methods that are contained in one big object because you didn’t know
[00:16:59] where else to put it. So we want to avoid these massive functions that are just filled with
[00:17:05] imperative code. And finally, number four. So number one, poor variable naming. Number two,
[00:17:11] tag along code. Number three, container functions or God functions, God objects.
[00:17:17] And number four, mixing presentation with your logic. Now, hopefully you’re not
[00:17:23] surprised by this. Hopefully you’ve heard this before. This has been around for a very long
[00:17:28] time. Separating your presentation from your logic is not a new idea. Of course, there’s a
[00:17:34] whole set of refactoring patterns and software design patterns that recommend separating your
[00:17:40] presentation from your logic. But this particular space is even more important than it has been
[00:17:45] in recent years, as we have a lot of powerful and interesting libraries and tools that allow
[00:17:51] and sometimes even encourage these two things. So let’s get started.
[00:17:53] to be mixed. React is a great example of this, as you could return markup inside of the same
[00:18:01] function where your logic is. And in fact, you can intersperse some logic in that markup. They’ve
[00:18:07] gone a little bit to the point where it’s a little bit more difficult to do that, but it is possible.
[00:18:14] And we want to avoid this issue by simply separating those methods from one another
[00:18:19] and using templates for presentation when possible.
[00:18:23] This doesn’t necessarily mean that you have to separate these responsibilities into different
[00:18:28] files. This is the common misconception. You don’t have to separate them into different files,
[00:18:34] but rather it means that the logical method or function you are writing should be agnostic
[00:18:40] to how the presentation will use the output. Let me say that again. You want to create
[00:18:47] two methods, one that does your presentation and one that does your logic.
[00:18:53] And your logic method should not care about how you wrote your presentation method.
[00:19:01] Your logic method should not care about how you wrote your presentation method.
[00:19:05] Now, if you can grasp this, it’s going to change the way you write code forever. It’s an incredibly
[00:19:11] powerful concept, and I highly recommend that you at least try to write code this way and see what
[00:19:17] it does to your workflow. See what it does to the maintainability of that code. I think you’re going
[00:19:23] to be surprised. Thank you so much for listening to Developer Tea today. And I hope you enjoyed
[00:19:29] today’s episode. By the way, Developer Tea was just launched. I’m recording on the day that it
[00:19:35] was launched in Google Play. If you are an Android user and you’ve been waiting on a good Android app
[00:19:43] or a good place to pick up the podcast on Android, this is your perfect opportunity.
[00:19:49] At Google Play, they have the podcast directly available. Of course, that will be in the show
[00:19:54] notes at spec.fm. Thank you again to FreshBooks for sponsoring today’s episode of Developer Tea.
[00:20:01] If you want to get your invoices paid faster, if you want them to be paid online, if you want
[00:20:07] someone to handle the awkwardness of sending late payment notices for you, go and check it out.
[00:20:13] There’s a free month at freshbooks.com slash developer tea. Make sure when you sign up that
[00:20:19] you put developer tea in the how did you hear about us section. And of course, all of those
[00:20:24] details will be found in the show notes at spec.fm. If you’re enjoying the show, make sure you leave
[00:20:30] a review in iTunes. This is the best way to help other developers find developer tea. Once I know
[00:20:36] exactly how Google Play system works, I will tell you how to leave a review or how to help us out
[00:20:42] on Google Play as well. Thank you so much for listening. And until next time, enjoy your tea.
[00:20:49] Bye.
[00:21:19] you
[00:21:49] you