c o d i n g f r o g s

croaking about programming, programming languages, software engineering, and the business of software

12Aug/090

Discipline as a Prerequisite to Critical Code Contribution

Merriam-Webster's dictionary defines discipline as:  "..."

Nah.  Just kidding.

Most software teams I've worked on have had some degree of discipline around what code changes go into the codebase.  This tends to take the form of:

  • Any change should be associated with a defect or feature that is documented somewhere.
  • Commit small, isolated, related changes, all associated with a single defect or feature, that can be easily rolled back.
  • Test changes before committing them; avoid breaking the build at all costs.

That last one seems most obvious, but it is so critical that it has to be stated anyway.  Think of it this way:  If you work for me on an already functioning product, I would rather have you do NO WORK AT ALL than to break the build.

Of course, I would not pay you to do no work at all, either.  But breaking the build is taking the product in the opposite direction from where we want it to go.

Some time ago I worked on a software team* where a team member had a problem with this kind of discipline.  Details don't matter too much, but the net effect was that whenever this person made a commit, the rest of the team would tense up and hold their breath as they integrated the updates.  This person had broken the build enough that his/her commits weren't trusted by the rest of the team.  And even if the code would compile and run, you still didn't trust the changes because this person would often sprinkle in little changes hither and yon that were not tied to a documented defect or feature, and often wouldn't even call out the changes in the commit message.

(As a slight distraction here, I'll point out how frustrating this is when the team member works in the same office as you, as cited above.  When that person works remotely, it becomes MUCH MUCH WORSE.)

I discussed this with my boss one day who wasn't sure what to do.  We had a person on the team who was obviously very talented, but who was just not following good practice despite repeated requests to do so.  I offered up the suggestion that I'm restating here, which is basically the following:

Disciplined software engineering should be a prerequisite to having the rights to make critical code contributions.

In other words, no matter how talented a programmer is, they shouldn't be allowed to contribute code to critical parts of the product if they do not exhibit sufficient discipline to be there.  So what are the "critical parts" and what is the "sufficient discipline"?  The critical parts are the parts that, if they are broken, the software doesn't perform it's primary function.  For a product like Firefox, the "Help" dialog is almost certainly not critical, but the HTML parsing engine definitely is.  The sufficient discipline is what I outlined above, but primarily centered around not breaking the build.

So to summarize, what it means is, someone who continually breaks the build should be disallowed to commit changes directly to the critical parts of the product until they earn that right back by adopting the discipline required.  Of course, if you are that free-spirited maverick, there's a pretty strong incentive now to change your approach.  You may not be paid to be disciplined, but you are paid to deliver software, and if you can't deliver software because your approach is irresponsible, this should encourage you to get on track.

Some teams choose to approach this by building elaborate systems that enforce proper behavior.  I could build a complex checkin proxy that automatically merges my changes with the latest changes in the repository, builds the product, and then runs the tests (there are tests, right?), and then only makes my commit once all of that passes acceptably.  That's nice and all, I suppose.  But it seems like a lot of infrastructure, overhead, and process to impose upon the whole team, when to me it seems reasonable to expect that professional software engineers have enough discipline to do this on their own.

So if you aren't doing this now, how do you go about changing?

Well, you've gotta have a suite of automated tests in order to do any of this - a "broken" build is defined as one that does not pass the automated tests.  If you do not have any automated tests, it is time for you to repent, my son.  I do not have time to go into this here, but you must confess your grievous sin and atone by writing an automated test and adding it to your build process.  Just one test is enough to get started - but it MUST be available as a part of the normal build process.  Then every time a build passes the test suite but is, in fact, broken, update your test suite.

Now that you have automated tests, insist that your developers do the following before they commit:

  • Update.
  • Build.
  • Test.

See?  It's easy.  If the tests pass, they can commit.

Now it is time for you to be disciplined.  Committing code that does not pass the tests is a naughty thing to do.  Do not let your developers be naughty.  Take immediate action.  I think I'd take the following approach:

  • First time is a meeting with the boss.  Go over the process.  Make sure they understand the process and what happened.  Personally, it seems like it would be tough to misunderstand, but hey, things happen.  Don't be presumptuous or condescending.  This meeting alone might be enough to get most people in line.
  • If the problem continues, require peer review before checkin.
  • If the problem continues, another meeting.  This time, express that all of their current assignments have been reassigned to other members of the team, and they are being reassigned work that is not critical to the functionality of the project.  Let them know that you are concerned about the impact this will have on their performance, because they are expected to contribute at a higher level than what their new assignments will allow.  They have to demonstrate changed behavior and commitment to discipline in order to earn the right to do the important work again.
  • If the problem continues after that, it is probably performance-improvement-plan time.  Or mutual-agreement-that-they-find-a-different-employer time.
*(To my faithful readers who think they know what situation I'm speaking of, may I remind you that I've worked for seven different software companies and thirteen-ish different software teams over fourteen-plus years in this career, so be careful what assumptions you might make.  Thank you.)
7Aug/092

Actions Speak Louder Than Code

It took me a while, but I finally settled into my routine and got to where I'm reading my RSS feeds most days again.  I was going through the posts of the past month or so, since the job change, and ran across this article on the "Making Good Software" blog about things that keep someone from being a good software engineer, outside of (and often in spite of) an ability to engineer software.

I'll summarize here.  It isn't my intent to plagiarize; if you are remotely interested go read the article.  Here are the things:

  • Lack of discipline
  • Big ego
  • Poor communication
  • Forgetting the customer
  • Lack of proper work prioritization

I have known many of these people during my career.  Indeed, I was one of them.  I remember coming to Novell from IBM almost ten years ago.  I thought I was pretty hot stuff and I made sure my team knew it.  In fact, I actually said (this is embarrassing to admit) on more than one occasion, "There are people who know C++ better than I do, but I haven't met any of them."  My ego surely made me hard to work with.  It definitely was a cause of friction between myself and my management chain, and ended up being a (deserved) source of frustration and difficulty for me, until I recognized the problem and started working to address it.

I'm pretty ashamed of having behaved that way back then.  I hope I'm better than that today.  I guess recognizing the weakness is a good first step.  Fortunately for me, back then I was on a really great team with a lot of very capable, patient, and talented engineers that waited for me to learn from my mistakes and to grant them the mutual respect they deserved.  I consider myself pretty fortunate to have been able to learn from them what real software engineering is about.

Over my career I've had to work with people like this from time to time, software engineers that manifest one or more of these traits.  Sometimes these guys are pretty talented technically.  I've felt sorry for them as I've observed, realizing that these weaknesses are going to hold their career back until they recognize them and work to overcome them.  No amount of programming prowess will compensate for it.  And what's even worse is, often because these people have the personality issues they have, you don't get anywhere by trying to bring these weaknesses to their attention; they are often unreceptive to this type of feedback.  Like I said, you just have to wait until they recognize it themselves.

I can imagine being in a performance review with someone like this, having them explain to me all the technical awesome they did, and me replying, "Your poor soft skills are shouting so loudly that I cannot hear your technical awesomeness."  Or, as I said in the title, actions speak louder than code.

I really believe this is true.  To write software professionally, of course you must have technical ability; however, this is a necessary but not sufficient condition for greatness.  The best software engineers I've had the fortune to work with in my career, past and present, not only had awesome technical ability but did not exhibit weakness in these areas.  And I'll tell you what:  Those teams are wonderful teams to be a part of.  Those teams create strong. uplifting work environments and are able to deliver great products that meet customer demand.

Another way to say this is, in order to be a good software engineer, you must first be a good employee.

In fact, I'll tell you how important I think this is.  The ability to mitigate or eliminate these defects from a software engineer's persona is so important to me that, if I had my own company and were making the hiring decisions, I would not hire a candidate that I knew had these problems, no matter how incredible their technical ability.

A person with these weaknesses is really only suited to be set to the side to work on a special side R&D project where interaction with other employees is limited, and they don't have to interact with customers at all.  Problem is, those kind of projects are either a) strategically important to the long-term future of the company, or b) of little to no real value, or c) a combination, often high potential value but with a lot of inherent risk that causes the real value to be low.  If the project is strategically important or of high value, do you really want to reward the biggest jerk in your company by giving him the highest profile assignment, leaving your best engineers to maintain the legacy project?  Wouldn't you want to have someone working on that high profile assignment that knows how to collaborate with others and assemble all the best ideas to solve the problem the best way, even if that solution isn't his/her own?  Contrariwise, if the project is of little real value or has so much risk that it offsets the real value, why even do it at all?

Nope.  In my company, if I were ever to have one, I wouldn't hire or keep an employee who had these weaknesses and was not committed to addressing them.  I've seen the difference, both in morale and productivity, between teams where they don't have these problems and teams that do.

4Aug/091

Software Engineering No More

The software development community is abuzz because of this article written by Tom DeMarco, author of that seminal work "Peopleware" that I ordered from some joker on eBay about six weeks ago but has not come yet.

You really should read the article.  I say this because I assume that you are a software engineer, like me.  Otherwise, let me summarize it for you.

Nah, that'll take too long.  Let me sum up.

DeMarco basically says in the article the best software development on the most valuable software products with the highest degree of utility happens in the absence of control and measurement.  In other words, everything every software engineer on earth was taught about software engineering in college is wrong.

Yeah, that's pretty much what he's saying.

This has led to a lot of discussion around what we call all those people that we used to call software engineers just last month.  The impetus is that if the best software is created by not managing or quantifying the work and the deliverables in the project, is this really engineering per se?

Well, I've known this for a long time.  I just haven't said anything about it.  Seriously, stop laughing.  I don't expect you to believe me.  In fact, I'm happy to give credit to all the other people.  But it is certainly true that, although I've had that word in my job title for well over a decade now, I've felt for some time that software engineers are unique from other types of engineers.  Indeed, good "software engineering" requires creativity and artistry as much as it requires engineering.  "Software craftsmanship" is the term Jeff Atwood at Coding Horror is pushing today; "Software Artisan" is another term I've heard today as the new replacement for "Software Engineer."

Whatever.  I know what it is I do, so you can call me a Software Masseur if you feel like you must.  I'll just keep doing my job like always.

Joking aside, this article is a big deal because someone (more specifically, someone people will listen to) has finally come out and said what we've felt all along - trying to measure and control the creation of software is not helping, primarily because it is at least as much a creative process as it is a technical one.  Convincing the Employees Formerly Known As Software Engineers around the world this is true is not going to be a hard sell.

Convincing their employers and customers, on the other hand, is going to be tough.  That's because the customers have come to expect that they will know what features will be in what products by what date, and they aren't likely to give that up willingly.  They need (or think they need) to know all of this so they can plan - when to buy their next computer, when to get trained on the new version of a product, when to rollout system updates to an enterprise, when a partner can promise the delivery of new functionality to their customers, etc.

Interestingly, some organizations are able to avoid this expectation of their customers.  Open source projects are particularly good at this.  Eclipse, for example, delivers a release every year but makes no promise as to what features will be included in that release; other projects, like Linux and Apache, release whenever they feel like it.

I remember writing a software product that was going to be delivered as Apache modules for Apache 2.0, way back before Apache 2.0 was officially released.  We e-mailed the Apache project during development to ask when Apache 2.0 was scheduled to ship, and they said in essence, "We don't know.  And, we don't publicize or even set release date goals.  We ship it when it is ready."  Of course that made it hard to plan, but part of me secretly wished I could get paid to work on Apache.

Open source projects are not the only ones that do this, however.  I defy you to figure out when any given Google app will ship, for example.  And consider Blizzard Software, one of the most successful video game companies EVER (ever heard of World of Warcraft?).  As I understand it, they are like Apache in this regard - their product will ship when it is ready, and not a day before, and it doesn't matter what big holiday or trade show is coming up.  And so far they've done alright.

And then there's Duke Nukem Forever.  Wait...