Your Coworker’s Bad Code: Having The Hard Conversation
Editorial Note: This post was originally written for the SmartBear blog. You can check out the original here, on their site. If you’ve never had the chance, take a look at their blog in general. A lot of good authors over there.
Last time, I talked about how to prepare for a tough conversation with a coworker about having bad code. This included understanding what not to say and creating a game plan of specific shortcomings to address and concrete outcomes you want from the conversation. This time, I’m going to talk about how to actually engage with your teammate, who I’m calling “Bob.”
Engage
Having built your case ahead of time, it’s time to go have a chat with Bob. You’re calm, you’re rational, you have a legitimate argument, and you’re all set for a constructive dialog…but the lead in for the conversation threatens to be awkward. What I’d suggest doing to put the conversation in more natural terms is to ask for his help. “Hey Bob, I’m chasing a defect through the code and it led me to this method of yours. It’s a little hard to follow at first glance, so I was hoping maybe we could trace through it together?” Now you’re not coming over to preach to Bob about the evils of his code but rather to ask him to help you solve a problem.
Once you’re looking together at a screen and starting to dig in, one of the most effective ways I’ve found to surface code problems is through the Socratic Method. Instead of telling Bob that the method is too long, ask a series of questions. “Wow, good thing you’re here—this is a pretty long method with a lot going on. How long do you think it would take the average team member to understand it?” “Huh, wow, three or four hours seems like a pretty long time to spend trying to understand a method, don’t you think?” “What if it were smaller?”
Making proclamations of fact or strongly stating opinions tends to put people in a defensive posture. Asking questions, even leading ones, doesn’t get people’s hackles up as much. They tend to join you in problem-solving mode rather than argue against you in debate mode. Still, asking questions this way may not lead to the desired outcome, which is why you’ve done your homework. Switch gears from the questions to statements of your experience and how you feel. These are inarguable.
“I get that you think breaking up the method would just distribute the complexity, but I spent hours trying to understand this. I don’t have the same problems in Alice’s code where she uses lots of small methods.” There’s nothing Bob can say, so far, to argue with this, so it’s a good premise for a call to action. “You can find a lot of literature and studies out there about small methods correlating with fewer bugs, and I know I’m not the only one on the team that prefers to read and write code that’s more compact. What do you think? Can we try pairing up and refactoring this a bit? It might help reduce the defect count originating from features that you’ve implemented.”
That last line is the critical last piece to the engagement puzzle. Bob probably can’t argue with your well-researched position, and he certainly can’t argue with how you feel, but he could still balk at changing his approach. You need to focus on how the new approach benefits not only others or the codebase in general but also specifically Bob himself. No one wants to write bad code and suffer the consequences, so help them understand that life can be better.
Maintenance
As I’ve said, you’re not going to take someone that writes bad code and turn the whole ship around in a sitting. The first engagement is about establishing a relationship along these lines and setting the stage for more talks. To do that, you have to be prepared and patient, willing to nudge gently but firmly, and opportunistic in looking for a line of reasoning that strikes a chord. If you can show Bob the difference and convince him of the benefits of adopting a new approach, future collaborative improvement sessions will start to happen naturally. Often times, they’ll happen with Bob being eager to learn. I’ve personally been in a lot of groups where building trust in this fashion has led to unsolicited requests to review others’ code and offer feedback. If that happens, you’re in an excellent place.
Over the course of time you and Bob can work together on a broader strategy of code improvement. Even if he’s receptive and eager in the initial conversation, this kind of ongoing maintenance will be required for going from “Bob writes poor code” to “Bob writes clean code.” This will require cataloging the differences between good code and bad code, keeping track of them, and working strategically with Bob one one or two of them at a time to help him get better. As he practices the easier ones, you can gradually introduce more and more to gently push him out of his comfort zone, toward cleaner code.
So, in the end, how do you tell Bob that his code sucks? Over a beer, a year or two later, when marveling at how far he’s come: “I didn’t want to discourage you back then, but your code really sucked. You’ve come a long way. Good job.”
After all that, you think it’s necessary to tell him a year or two later over a beer that “his code sucked”? Why would you bother to do that? The only reason to do so would be that your ultimate goal was really to figure out how to (eventually) inform Bob that you think his code sucks—finally accomplished a year or two later in a very long end game—rather than simply to bring in line with what your opinion of “better code” is. How do you think telling him this would NOT 1) make you an ass and 2) put… Read more »
The last paragraph wasn’t meant to be taken literally as a suggestion for a formal part of the process. What I was intending to convey was, “if you’re going to be blunt with someone like that, make sure you’ve earned credibility and trust, and developed a rapport or even friendship that makes the bluntness appropriate.”
I agree that if you and Bob barely have a working relationship, inviting Bob out for a beer to rehash a 2 year old code review would be a rather psychotic thing to do.
“Huh, wow, three or four hours seems like a pretty long time to spend trying to understand a method, don’t you think?” “What if it were smaller?”
Sounds pretty passive aggressive to me. I’d rather someone was straight with me rather than asking all those patronising questions.
I agree with the principle that you need to be gentle when mentoring, but those examples would just get my back up if I was on the receiving end.
It’s been my experience that people who prefer to dole out and receive blunt feedback will (not surprisingly) ask for blunt feedback. So if I approached things this way with you, and you said, “just lay it on me,” then that’d be fine. But, on the flip side, people who are sensitive to blunt feedback will just shut down when faced with it, making recovery of the rapport a lot harder. They won’t say, “hey take it easy” — they’ll just quietly hate me. So, it’s like a Pascal’s wager of sorts. I tend to take the downside-minimizing approach. Also,… Read more »
That’s fair enough. My comment above was probably a bit blunt :). What I was trying to get at is that questions like those above are not really questions at all, it’s telling them what to do, dressed up as pretending to explore a problem together. I read part 1 since commenting and I’m really on board with the general thrust of what you’re suggesting, it’s just those specific examples that I had an issue with. You’re absolutely right about social cues, I find the most important part of mentoring is really paying attention to the other developer, so you… Read more »
Reading through the particular questions from the post, I see your point. Those are more leading than the average questions that I’d ask in this situation. Usually, I’m asking questions out of genuine curiosity. In the face of someone who seemed to see no problem with gigantic methods, I might opt instead to state my preference and some supporting literature, rather than asking. However I get there, the thing I’m really looking to do is create the opportunity for people to figure things out, as opposed to me just telling them. I suppose that’s because I’d prefer feedback of this… Read more »
I’ve had to have this discussion a few times. I guess as a team manager I’m in a bit more position of power in that I can say “do it this way”, rather than just a go to guy or team member. As lovely as a “how do you think we can solve this” long game solution is, it’s also very time consuming. The question you need to ask is are you training Bob, or is Bob already suppose to be a professional and productive member of the team? The question is, should you keep Bob, or let Bob go… Read more »
If you’re working with a more seasoned developer, then the question+answer process becomes more real and less disingenuous. The danger there is when you say “do it this way” and you’re actually missing out on the valuable insights that come back to you. For me, the above scenario works best when it genuinely *is* a two way exchange of ideas, even if the net flow is from yourself to the other developer.
When I wrote this post, it was very much about how peers should interact with one another. (It was written to a prompt to this effect.) The idea being, “hey, this guy on your team writes bad code — how do you tell him that?” The topic of managers evaluating the team is something I’ll cross post at a later date here, actually 🙂 tl;dr opinion I have with respect to this is I’d prefer dev managers not to be evaluating developers on the basis of technical details (favoring outcomes instead). That’s been particularly hard for me, personally, in management… Read more »