For a team to work on software, you need a few things. The first thing you need is a good team. I’m still figuring out how to form, find, grow, and lead a good team. This stuff has been written about extensively, and everybody is wrong. Alternatively, nobody really knows how, because every situation is different.
But that’s not the point this time around. At the moment, I’m just thinking about tools. I think folks have probably written about this stuff before, but it occurred to me that there are a few group-level technological things needed to run a good software engineering team (individually we need good code tools, text manipulation, editors, whatever, but I’m thinking group-wide stuff). Here’s what I think is necessary:
- Source control. This one has been written about to death. Doesn’t make it any less necessary.
- Build system. This one has been written about less, but is no less important. Continuous integration and builds are ideal, but at bare minimum it needs to be trivial for anybody to build the entire system, from either the reference copy or their branch, with virtually zero effort.
- One to one real-time communication. This means some sort of instant messaging. Sorry. Engineering isn’t a telephone sort of thing, and we’re not always in the same room. We don’t even always want to be in the same room.
- One to many real-time communication. IRC. It’s simple and well understood. And it works great. I’ve seen it used in huge multinational companies where it was required for every employee, and it was one of the greatest things ever. A lack of this facility means a lot of redundant questions, and a lot of redundant conversations. It also means that non-engineers are going to be even less likely to answer questions for each other, which means more engineering time tied up with not engineering.
- One to one high-latency communication. Email is pretty ubiquitous, so this is a no-brainer these days. Still important.
- One to many high-latency communication. Newsgroups, wiki, mailing lists, blogs, or all of the above. Engineers need a way to debate things. To think over time. To collect their thoughts and chew on it. They also need to bitch. It’s our favorite pastime.
- Bug tracking. I think this is a lot more important than feature tracking. I think most engineers can keep straight the stuff they want to work on. But there are always bugs, and they’re easy to forget, especially if your users are polite and not complaining to you every day. This is more problematic when your users silently quit you.
Honestly, that’s a lot of stuff, but I think it’s all necessary. I think if any of those things are missing, it’s going to make it harder for a software engineering team to succeed. Unfortunately, just having these things is hardly sufficient. For each of the things above, I think it’s also necessary to impose some constraints:
- Speed. Each system has to be fast. Really fast. If it’s not fast, it either won’t be used, or it will generate hate. Both of these are dangerous things in a software engineering organization. Remember, engineers like to complain. Complaints propagate at a speed only exceeded by rumors. If bug tracking is slow, engineers won’t bother checking up on bugs. If source control isn’t blazing fast, it won’t be used. If the build system can’t spit out a complete build instantly, it’s less likely to be used when it matters most. Every single system has to be fast, no exceptions. Engineers love speed. Sorry.
- History. Every system needs it. There is a serious amount of pain that comes when one can’t determine the history of a change. Or the history of a bug. Or the history of a conversation. Nothing sucks more than having the same conversation twice, or not being able to refer to a past conversation. I’ve seen some really nasty examples of having history, and the value of history being recognized, only to have it sacrificed and made unavailable in order to keep things fast. Speed/history isn’t a trade-off. None of these constraints are trade-offs. They are all requirements.
- Search. Both for the current state and the historical. One needs to be able to find anything in any of these systems. This needs to be fast too. If people can’t find bugs, they will file redundant bugs. If people can’t find past conversations about a topic, they’ll waste time having the same conversation.
- Robustness. If a system is unreliable, it will not be used. It will generate frustration and whining. You don’t want whining; it eats away at your organization like a cancer. You want people not to even think about reliability, because they never had to think about it. The best systems are those that aren’t appreciated. Take pride in never hearing complaints, even if you never hear a complement. This is far better than being hated for a fickle nature.
- Scalability. Fundamental issue here; it’s the same as engineering software itself. If scaling isn’t considered from the beginning, it’s going to be a giant mess to add in later. Same goes for these systems. Scaling can’t be an afterthought. Even if your project is small now, it may not be some day. Even if it stays small forever, it’s good to be in the appropriate habit. Spend the effort up front, it will be worth it to never worry about these things in the end.