How to Disagree without Being Disagreeable
In our jobs as programmers, sometimes you have disagreements with other people about how something should be done. How you handle those disagreements affects your work life, how much you enjoy your job, and your career prospects.
Whether it's disputing time estimates with a project manager, suggesting a different table layout to a senior programmer, trying to settle a coding style issue with a colleague, or deciding whether a program's actions are a bug or a feature – the conversation doesn't have to be unpleasant or to create conflict.
Eliminate binary thinking and language.
The first thing to remember when dealing with disagreements is to not think of things as black and white. We programmers have a tendency towards binary thinking, which can be good when working with computers, but it's rarely helpful when working with humans. Words like "right," "wrong," "good," "bad," "always," and "never" are examples of binary thinking, but situations are rarely so clear-cut.
Binary words have two negative effects. First, they shape how we think about a situation and help us ignore the middle ground. Second, they can be insulting and off-putting to those we talk to. If you find yourself thinking "This is code is bad," stop and rephrase it, even if it’s only in your head. It helps you understand the situation better, and it makes it less likely that you blurt out to someone, "Your code is bad."
Instead of saying, "That screen layout looks bad."
Say: "I think the user's going to be able to follow read down the page more easily if the fields are grouped together differently."
Instead of saying, "That's the wrong way to do database inserts."
Say: "I'm concerned that under load we're going to see slow response times. My experience is that SQL Loader will do it in about one third the runtime."
Separate fact from opinion.
Work only with facts. Recognize that your opinions are only valid based on facts you state. For example, the following are all opinions or judgments:
- "Perl is too slow. You should do it in C."
- "You can't maintain SQLite databases."
- "Nobody likes Flash on webpages."
How many times have you heard or read sentences like these stated with absolute conviction – as if they were facts? These sorts of statements are not only opinions dressed up as facts, but they also show binary thinking.
If you find yourself thinking this way, try reframing like this:
- "I prefer the raw speed of writing in C in many cases."
- “I've been frustrated in the past maintaining SQLite databases because it doesn't support ALTER TABLE."
- "I don't like Flash on webpages."
It’s best to present your perceptions in fact-based “I” phrases: “I prefer,” “I have found,” “In my experience.” If nothing else, other people can’t argue that you’re wrong in quite so confrontational a manner, because they can’t claim you don’t perceive something you perceive. And they don’t feel attacked, because you’re talking about how you see things, which simply may not agree with how they see things.
Seek first to understand.
When we first encounter something we see as a problem, it can be easy to jump to the conclusion that someone made a bad decision, or, worse, is just plain stupid. Resist that feeling and give others the benefit of the doubt. Expect that there is more to the situation than what you're aware of.
Find out about the situation’s history. In many cases, choices were made in the past for reasons that are no longer relevant, and it's okay to change things. Sometimes they must stay as they are. In either case, it's not unlikely to find that the person who wrote the code was doing it under someone else's orders.
Go into detective mode, aiming to learn all you can about a situation. Adopt the attitude that there are facts you're unaware of, and try to uncover them in the name of science. In fact, expect to have your opinion changed so that you keep your mind open. You just might learn something.
Seek first to understand the situation, and only then to have your views understood by others.
Know your place.
Sometimes your position in the organization may means it's inappropriate or not in your best interest to voice a disagreement. Maybe you're new in the group; or maybe you're in a group that doesn't have control over the area of disagreement, and you should keep it to yourself.
Sometimes what you disagree with is not in your area of expertise, or outside your area of concern. I sat in a staff meeting once where a programmer told his grandboss that he didn't think that the company's long-term strategies were sound and that we should work around them when designing the current project. It didn't help his standing in the organization any.
In other circumstances, it's not appropriate for you to disagree with a decision that's been made or to criticize code that's already been written. When the project is half done, it's not helpful to suggest that PostgreSQL would have been a better backend than MySQL.
Know your responsibilities.
The flip side of knowing your place is to know your responsibilities. As a programmer, one of your responsibilities is to raise concerns to the project leader or management about things you see that could be problems. If you're concerned about code that's insecure, or that's going to run slower than it should, or that's not going to be maintainable, or any of a number of other problems, then it's your responsibility to raise the concerns.
Raise your concerns, making sure that they've been understood. Then leave it alone if those above you choose not to act on it how you might want them to.
Be careful of what you want to "fix."
When it's time to discuss your disagreement, avoid judgmental language. Binary words like "bad" and "wrong" can be inflammatory, but so can judgmental words like "broken" and its counterpart "fix."
"Fix" is awfully inflammatory for such a small word. It implies that something is "broken" or "wrong." "Fix" has no place when discussing design decisions, or when referring to code that works but could be improved.
For example, you might find some duplicated code in the codebase. Telling a coworker, "I found some duplicated code, so we need to fix it" implies that the code is broken, which is unnecessarily provocative, especially if the coworker is the one who wrote the code originally. Duplicated code is not broken. It's just not ideal. Instead, try saying, "I found some duplicated code, and I'd like to refactor it."
Instead of saying, "You should fix those function names" say, "I think future maintainers will have less to figure out if you use more descriptive function names."
Beware the word "just."
The word "just" is a loaded word, too; it implies that a potential solution is simple and obvious. For example, "Can't you just add a flag to the user table?" says to the listener, "The solution is obvious and you should have thought of it already and I am here to present it to you: Add a flag to the user table."
Chances are, the obvious solution that you suggest with "Can't you just" has already been thought of, because it is obvious, and discarded for reasons that you have not thought of or because of constraints you don't know about. If that's the case, then it's condescending to the listener for you to ride in on your horse spreading wisdom that doesn't work.
If you're tempted to say "Can't you just…" bite your tongue and rephrase the statement with the expectation that there's a reason it's not the solution chosen. You want to be helping with the solution, not handing it down your wisdom from on high. For example: "The first thing I'm thinking is adding a flag to the user table, but I haven't thought through the implications of that yet."
Instead of saying, "Can't you just change that column from integer to varchar?" say, "The first idea I had was to change that column from integer to varchar, but I don't know what other effects that might have." Or: “Did you consider changing that column from integer to varchar?”
Similarly, avoid "obviously," as in "We should obviously use Ruby for this project." It tells the listener that he's stupid if he disagrees, or if he doesn't know something that you know. Instead, say, “I think Ruby is the best choice of language on this because of X, Y and Z."
Leave out the drama.
Back in the late 80s, early in my career, I disagreed with my boss about some design decision. I don't know what we were arguing about, but I'll never forget my dramatic declaration at the end where I proclaimed, "If we do it your way, we might as well not even do the project!" I'm embarrassed just thinking about it today.
I don't know what I was thinking at the time. I don't know if I expected that Rick was going to say, "Wow, Andy, I didn't realize you felt so strongly about it, we should do it your way." Maybe I'd been watching bad soap operas. Whatever it was, my fit of drama did me no good, and certainly didn't get Rick to change his mind.
Know why you're disagreeing.
Before you pipe up and say, "We should do it via X instead of Y," begin with the end in mind. Think about what you're trying to achieve. If you don't have a goal, and your disagreeing isn’t likely to achieve that goal, then it's probably best to keep it to yourself.
For example, if you're in a code review and there's a block that's using braces counter to the department coding standard, then you bring it up so that the code can be adjusted to match the rest of the codebase.
On the other hand, if you're in a code review and you're thinking "I've always hated K&R braces, and I think we should switch to GNU style," consider the value of suggesting that. Do you think that you're going to get the coding standard changed on the fly in the middle of a code review? No? Then keep it for another time and a better venue.
These disagreement guidelines aren’t good only for avoiding friction with your team and your users. They also help you get your own way, more often. By focusing on the goal and how you see an issue preventing its achievement, you can avoid a combative situation in which “winning” and “losing” become more important than doing the right thing.