How do you tell someone they're writing bad code?
Categories:
Navigating Code Quality: How to Address Bad Code Constructively

Learn effective strategies for communicating code quality concerns, fostering improvement, and maintaining positive team dynamics without causing offense.
In software development, encountering 'bad code' is inevitable. Whether it's a colleague's work, legacy systems, or even your own past contributions, identifying areas for improvement is crucial for project success and maintainability. However, delivering this feedback effectively requires tact, empathy, and a focus on solutions rather than blame. This article provides a comprehensive guide on how to approach these sensitive conversations, ensuring that feedback is received positively and leads to tangible improvements.
Understanding 'Bad Code' and Its Impact
Before addressing the issue, it's important to define what constitutes 'bad code' and understand its potential consequences. 'Bad code' isn't just about syntax errors; it often refers to code that is difficult to read, understand, maintain, or extend. It can lead to increased bugs, slower development cycles, higher onboarding costs for new team members, and overall technical debt. Recognizing these impacts helps frame the conversation around project health rather than personal criticism.
flowchart TD A["Identify 'Bad Code' Instance"] B{"What is the Impact?"} C["Increased Bugs/Errors"] D["Reduced Readability/Maintainability"] E["Slower Development/Technical Debt"] F["Difficulty Onboarding New Devs"] G["Prepare Constructive Feedback"] A --> B B --> C B --> D B --> E B --> F C --> G D --> G E --> G F --> G
Flowchart illustrating the identification of bad code and its potential impacts.
Strategies for Delivering Constructive Feedback
Delivering feedback about code quality requires a thoughtful approach. The goal is to educate and empower, not to shame or demotivate. Here are key strategies to ensure your message is heard and acted upon:
1. Choose the Right Time and Place
Avoid public criticism. Opt for a private conversation, a dedicated code review session, or a direct message. Ensure the person is receptive and not under immediate pressure.
2. Be Specific and Provide Examples
General statements like 'your code is messy' are unhelpful. Point to specific lines of code, functions, or patterns. Explain why it's problematic and how it could be improved. For example, instead of saying 'this function is too long,' say 'this calculateOrderTotal
function is over 100 lines and handles both pricing and discount logic; perhaps we could refactor the discount calculation into its own helper function for better readability and testability.'
3. Focus on Solutions and Learning
Offer concrete suggestions for improvement. Provide resources, suggest alternative patterns, or even offer to pair program. Emphasize that this is an opportunity for growth and shared learning.
4. Use 'I' Statements and Maintain Empathy
Frame your feedback from your perspective. Instead of 'You wrote bad code here,' try 'I found this section difficult to follow because...' or 'I'm concerned that this approach might lead to issues with X.' Understand that everyone has different levels of experience and might be under different constraints.
5. Follow Up and Offer Support
After delivering feedback, check in to see if the person needs further assistance. Offer to review the changes or discuss the concepts further. This reinforces your role as a supportive colleague.
def process_data(data):
# This function does too much!
# It loads, validates, transforms, and saves data.
loaded_data = load_from_source(data)
if not validate_data(loaded_data):
raise ValueError("Invalid data")
transformed_data = transform_complex_logic(loaded_data)
save_to_database(transformed_data)
return transformed_data
# Constructive feedback example:
# "I noticed the `process_data` function handles multiple responsibilities: loading, validation, transformation, and saving.
# This makes it harder to test and understand. What if we broke it down into smaller, more focused functions like `load_data`,
# `validate_data`, `transform_data`, and `save_data`? This would align with the Single Responsibility Principle."
Example of a function that violates the Single Responsibility Principle, and how to provide specific feedback.
Fostering a Culture of Continuous Improvement
Beyond individual feedback, promoting a team culture that values code quality and continuous improvement is essential. This involves regular code reviews, establishing clear coding standards, and providing opportunities for skill development. When everyone understands the shared responsibility for code health, feedback becomes a natural part of the development process, rather than an isolated event.