Styles

Sunday, November 16, 2014

Programming beyond writing code (Part 1)

I recently came across an article by Laura Klein titled "Your Job Is Not to Write Code". I read the article because I happen to agree - it's a software developer's job to solve problems, and too many developers focus too much on the code and not on the problem at hand. I was hoping for another point of view, or at least something I could share on Twitter. Instead, I read a condescending and destructive post from a myopic product manager. I'm going to write a blog post soon about why software developers should be problem solvers before coders, but today I want to respond to Ms. Klein's post.

Quote #1
Your job is to improve our product for our users. If you want to get technical about it, your job is to improve our product for our users in a way that improves the key metrics of the company. But honestly, you don't always have a lot of control over that second bit. You do, however, have an enormous amount of control over the first bit!
One of the reasons I got into programming in the first place was that I was excited about building solutions to make people's lives easier. Then after a while I realized that it's generally not the programmers who set the strategy, set the scope, determine the metrics for success, or even come up with the general design. But it's these things that really make the most difference in the overall quality of the product. It's this lack of control that led me to getting an MBA and searching for several years for the right position where I did have the control to make a real difference. So I disagree quite heartily about a developer/programmer/engineer having an "enormous" amount of control over anything other than code quality.

Quote #2
For one thing, you need to make sure that the code you write (writing code is still one of the main things you will do when doing your job, by the way) runs the way it should, even on users' machines. [Emphasis in original.]
Don't get me wrong - I've definitely seen the attitude that "it works on my machine so it's not my problem". But I've also seen the attitude of "I don't want to hear 'it works on my machine'! That's just an excuse, and a pathetic one at that!" The truth is I simply can't always predict how my code will react in other environments and you don't have the budget for me to try. So I will make my best attempt to prevent these types of issues from happening, but realize that problems that only crop up on other people's machines will happen from time to time. And don't be surprised if it takes a long time to fix - any programmer will tell you how incredibly difficult it is to find and fix a problem that he/she can't recreate.

Quote #3
Did you know that our users probably don't have brand new MacBook Airs with giant Thunderbolt monitors set at the highest resolution possible and running the latest version of Chrome? I checked. A lot of them have Internet Explorer on 4 year old laptops, so sometimes things you build don't work right on their machines. They're still our users, and it's still your job to improve the product for them, so please make sure that the code you wrote works in a reasonable number of environments.
On its own, this statement is pretty fair. No programmer likes to dumb down their code because of IE's stupidity. Given the tone of the rest of the blog post, though, I feel like I have to defend the programmer's point of view here, too. "Works in a reasonable number of environments" is an extremely vague term. What is "reasonable" to a product manager who is fielding complaints from users is almost always different than to a developer whose primary focus is putting in the latest whiz-bang features. It's important to take a realistic look at the actual number of people with problems. Are we truly talking about "a lot" of people? Or are there just three people who complain a lot? (And yes, I've been in situations where people have said that "a lot of people have problems" when in reality it was a very small but very vocal portion of the total users.)

Also realize that by putting in work-arounds for other browsers, you are increasing the costs of development, increasing the costs of testing, and increasing the costs of support. These costs increase exponentially the older the browser you want to support. You are also increasing the chance that the user experience for people on the latest and greatest technologies will be degraded. In other words, you can't make a website easily accessible to everyone, give everyone the best experience possible, and do so at a reasonably low cost. Therefore it is absolutely critical that everyone stays on the same page as to when these additional costs are worth it and when they are not.

Quote #4
So, to avoid [having problems crop up in production], you need to check your changes in production. Every time.
Here's another quote that if found in an otherwise normal blog post, I wouldn't think twice about it. Given the attitude in the post, though, it gave me pause. To explain why, here's a situation that happened to me earlier this week:

In the process of customizing Microsoft's Team Foundation Server (TFS) to be a time tracking system as well as a work tracking system, I needed to make a couple of unrelated changes. One of them was a configuration change to TFS, the other a code change to a customization I built. I made the changes in our development environment and everything worked fine. I pushed the changes to production, tested each change, and everything still worked fine. But when users got their hands on it, they uncovered a problem when taking a particular action that touched both of my changes.

Most people would understand that problems like this happen. This is true especially when you consider that, in this situation, I had the choice of either spending 4-8 hours really testing the app hard or spending 30 minutes diagnosing the problem, fixing the bug, and installing that fix. Some people assume that just because a bug pops up that wasn't found in testing, that the problem must have been an oversight of the developer pushing up code. And yes, I'm making assumptions here, but the tone of Ms. Klein's post makes me think that she's in the latter camp.

Quote #5
Of course, in order to check your changes in production, you're going to need to make sure that your code actually gets merged and pushed into production. I mean, you can't really check your changes in production if you just let them sit unpushed for hours or days. Push your code. Get it into production. Then run it and check it.
In principle, I agree. But if you actually use these words, you're more likely to do harm than good. If you are condescending towards your developers, their mindset will tend towards pain avoidance rather than problem-solving. And which do you think would avoid more pain, delaying pushing up code or pushing up code for someone who apparently thinks she knows your job better than you do?

(On a side note, I actually got scolded twice in the last couple months by a coworker who didn't like that I pushed up code outside of my determined release schedule, despite the fact that I did so to help her team out. Really? The usual response towards someone who goes out of their way is "thank you", not "why is it acceptable for you to not follow an arbitrary process".)

Quote #6
Another thing to remember is that sometimes users do surprising things, which means that it's not enough just to test that your code works under perfect conditions. You need to make sure that it does something reasonable even in error cases and zero data states and when the user does something you might not expect, like use the back button or make two accounts by mistake.
The vast majority of programmers know to test for certain conditions, both for usability and for security. But we can't anticipate everything. I wish I could attribute the source, but the quote "if you make something idiot-proof, someone will make a better idiot" comes to mind. Ms. Klein, as a product manager, should know that better than anyone. And like my response to quote #4, the law of diminishing returns applies here too. I could spend 8 hours trying to break an application or I could spend 30 minutes to find the cause of that same problem and fix it. There are times when spending the extra time is appropriate. There are others when it is not. It is unwise to always assume the correct course of action is one or the other.

Quote #7
There's one more important part to your job. You need to make sure that we can measure whether we're all doing our jobs well. That means adding metrics and analytics so that we can test the effects of our changes. If you expect the code you are writing to improve user engagement (by improving the user experience in some key way), then you need to have a way to learn whether or not you succeeded. How else will you know if your job is done? Because, as I've mentioned, your job isn't done until you've improved the product for our users.
There are two problems with this statement. The first is that a programmer may certainly suggest that this would be a good feature to put in, but if you read my response to quote #1, you'll realize that whether the feature actually goes in is generally not the call of the programmer/engineer. It is a business/design decision.

The second problem is I've never worked on a project that was big enough, or had a budget large enough, to warrant such an investment. I've certainly been in situations when such tracking would be useful, but at the end of the day, most people are going to throw Google Analytics at the website and call it a day. If you have the budget to write your own tracking, great! Have at it! But don't take it for granted that this is a feature that MUST go into a system! For most products the benefit is just not worth the expense.

Quote #8 (Article Subtitle)
I am lucky enough to work with a small team of fantastic engineers who truly care about their customers. If you are not that lucky, this letter is for you to share with your engineering team.
My advice for you is that even if you feel the need to share this with your engineering team, don't. There's very little chance you will do any good, but a very great chance you will do some harm. Here's what will happen:

If your team is clearly apathetic, then showing them this article will make you feel better for a short time, but then you'll get even more frustrated after it does no good. Your team will tear this blog post apart (sometimes making excuses in the process) and lose respect for you.

If you have a young development team, reading this article will cause them to get paranoid that they aren't doing a good job and they'll get overly-analytical about their own work. They will then start making mistakes by trying too hard and pushing too quickly, blowing your budget out of the water and killing your timelines.

If you have a good team, then they will be annoyed with the fact that you wasted their time to read an article that was full of condescension and devoid of any real solutions. Good leadership requires you to understand problems and find solutions. This article does neither beyond just "work better".

But as I said, I actually agree with more points in the article than not. I just think the tone is horrifyingly destructive. In the next few weeks I'll come out with a post with a different take on this problem.

No comments:

Post a Comment