Software Development Dogma that needs to Die

16066105308_1b5c7a34fd_z

The most important tenant I’ve learned in software is that you can’t be religious about anything. Not about languages, tools, methodologies, architectures, or practices.

Flexibility is key.

There are too many exceptions to every rule, and most “best practices” fail 20-30% of the time.

Despite this, I see fads running rampant through the industry.

I guess we’re just like fitness or nutrition with a new fad taking over every 10 years. Everyone thinks it’s a great idea until they don’t, when a new idea takes the old one’s place. Human nature dictates this ebb and flow of thinking.

Below is a list of the dogma that I see around me right now. I’m sure it will change in a few years, but this is current as of 2015.

  1. Test Driven Development (TDD)
  2. Pair Programming
  3. Mob Programming
  4. Love/Hate of Languages and Tools
  5. Mandated Unit Testing

I’m not trying to burn every process to the ground because I’ve used many of these methodologies with great success. But you’ll run into problems when you try to apply these universally.

Use whatever you want – you just need to be aware of the pitfalls and be prepared to accept the consequences.


 

1) Test Driven Development (TDD)

Does anyone actually write their tests first?

I think I’ve met 2 people who follow this practice. Both loved Test Driven Development and couldn’t stop telling me about it.

I understand the advantages. When you’re thinking about your tests from the beginning, you tend to structure your code better. Your classes are broken out nicely to support mocking, and you make everything injectable so you can test specific pieces of functionality.

But here’s the problem: I haven’t been able to find any data backing Test Driven Development. Software quality is notoriously difficult to measure. Sure you can say whether something is buggy, but it’s extremely difficult to get 2 identical teams to solve the same problem in a given period of time. It just doesn’t happen in the real world.

As a result, few reliable real world experiments testing software development practices exist.

Feel free to send me any data if you’ve got it, but I’m skeptical of studies that claim “such and such methodology increases the quality of the resulting software.” It’s just too hard to set up the experiment.

On a more practical level, many of the bugs in my code come from dealing with external services or libraries. The data is formatted in a way that you didn’t expect, or there was an assumption you made which was wrong, but you didn’t know until you interacted with the real live service or library.

Good luck writing your unit tests first in these situations. Of course, if the inputs and the outputs of the external service are well defined, then maybe this approach will work. But many times this isn’t true at all. Many times things aren’t documented, or you read the documentation wrong, or the documentation is out of date.

I can also understand situations where Test Driven Development would be useful. If I were writing, say, a math library, then the inputs and the outputs are well defined, and you have a definitive right or wrong answer for most of your functions.

If that’s the sort of software you’re building every day, then please, use TDD to your heart’s content. But how many of us actually build math libraries during our day jobs? 1 in 100?

 

2) Pair Programming

Through much of my software development career I’ve been subject to code reviews. Believe me, I know the value of a good code review, even if someone has to tell me to revert my code.

They’ve caught so many bugs and problems and stupidity on my part that I could never speak against them.

But pair programming is another world entirely.

Some people just don’t work well sitting side by side, with another person watching every single move they make.

I’m one of those people. I’m a lone wolf, and I like working alone. I’ve always been like that. It allows me the freedom to think in an environment free of judgement.

Some of the best programmers of our time are the same. They never pair. Take Linus Torvalds. Ever heard of Linux or Git? Linus got the meat of the minimal viable products for those projects done alone, without anyone looking after him.

In fact, the guy is so opinionated that pairing would have been a disaster.

I understand that in certain circumstances pairing can be beneficial. But I’ve read about lots of teams that require you to pair for everything, and I shudder.

I always wonder about the productivity of those teams. But once again, software productivity is notoriously difficult to measure, so I guess nobody notices.

 

3) Mob Programming

Holy shit. You’re going to put 5 people behind a single computer monitor and you think this is a good idea?

A buddy of mine was mandated to work like this for 6 months before he couldn’t take it anymore.

I found it completely baffling that his entire organization was convinced this was a good idea. Apparently they had never heard of the Ringelmann Effect. From Wikipedia:

The Ringelmann effect is the tendency for individual members of a group to become increasingly less productive as the size of their group increases

Once again, software productivity is already hard to measure, so organizations get away with this nonsense, even if it makes half their employees miserable.

 

4) Love/Hate of Languages and Tools

Languages

Languages are just tools. All of them have good and bad features, so I cringe whenever I interview someone who has incredibly strong feelings, one way or the other about a particular language.

I’d much prefer to have someone who understands which situation a particular language is good in.

Looking to throw together a quick web service?

You might want to go with Ruby or Python, since the implementation speed is so fast. But you’re going to run into problems down the line with maintainability.

Do you need something running on the bare metal in a cross platform way?

Then you might want to write your code in C/C++. Yes it’s still a good way to do it, even if you have to create a header file and a cpp file for every class. Yikes.

You get the idea.

Development Tools

I’m old school because I use VIM. Actually these days I’ve switched to Sublime Text, but I still use the VIM key bindings.

This makes most of my friends cringe, and rightfully so. Many times, I wish VIM was more like an IDE, but the text navigation is so fast that I’ve never switched.

If I have to build Java or a C++ project, then I’ll switch over to IntelliJ or Visual Studio or XCode, but Sublime is still my bread and butter.

My attitude on development tools is that as long as it makes you productive, who cares. Use whatever works for you.

 

5) Mandated Unit Testing

I’m a fan of unit testing. It’s saved my ass more times than I can count. I’ve worked on some large 10+ year old projects, with established customer bases, and I was glad they had good unit test coverage. It gives you confidence in new changes.

But I’m not a fan of being forced to unit test everything.

Why?

Unit testing is expensive

When you write tests, it means that task will take twice as long. Arguably, you get a bunch of that time back in more maintainable and bug free code that you’re confident in. The problem comes when you have to write tests for brand new projects, or your side project, or when you’re working at a startup.

You devote all this time to writing tests and keeping them passing, then the business model changes, and you have to throw away everything. You wasted a ton of your valuable time and energy engineering a project “correctly” and that project went nowhere. And unfortunately, most new projects don’t go anywhere.

As someone who has spent a large amount of time on side projects, I’ve learned that my most valuable asset is time and energy, and I don’t want to waste any of it fighting a mocking framework when I have no idea about the future.

On the flip side, it’s a problem when someone writes code quickly with no testing, and then it turns into a major product lasting for 10 or more years.

I believe this was the story with Gmail.

Then you wind up with an awful codebase that 100 other people are forced to maintain. New changes are so risky that nobody dares to refactor old, working code.

It’s a Catch 22.

So where do you draw the line?

I don’t have an answer for you. But I know that mandating anything isn’t the best solution. It needs to be at the engineer’s discretion.


What dogma do you see in the software world that drives you nuts?

Agile? “Extreme Programming?”

Leave me a comment below.

Photo Credit: barnyz