Let’s face it. Software development is very hard. Anyone telling you otherwise is lying or is not able to fathom the complexities involved.
Imagine the following scenario. You are given the task of developing a travel management system. The system is to be used to track an employee’s travel and expenses. You start it off by coming up with an initial design and UI mock-ups. Then you estimate the time and resources needed for this project. Finally you start building your app and finish it. Simple right? If only software development was this simple.
In a normal world, what started off as developing a simple application, in many organizations, would
evolve into a modern dinosaur. How? First, you are asked to integrate the new system with an already existing time entry system. Then they will need you to integrate with third party travel agent’s system. Next, you need to support multiple time zones, exchange rates, platforms etc. In the end you will be doing something like writing a java wrapper for your C code, which had embedded asm code blocks, and then packaging it as a plugin for your enterprise. Sounds familiar?
Fred Brooks in 1986, explained in his paper (from where the title of this post is taken from), that "there is no single development, in either technology or management technique, which by itself promises even one order of magnitude [tenfold] improvement within a decade in productivity, in reliability, in simplicity.” It is as true now as it was then.
But over the years, bronze bullets have been discovered to tackle the software development beast. They let you get around this beast but not completely slay it. Below are some pointers that can be followed to successfully get around the software development complexity.
Have a simple vision.
This simple vision should describe what you are trying to build. It should be of a single line, maximum two lines. At most places, you get a 100 page document describing what the product is going to do. This creates a problem because, people reading the document understand things differently from each other as to what the product is supposed to do. Instead try having a very simple vision for your project. When Google built Gmail, their vision was “Simple web mail client with lots of storage”, and not a big document to describe the features. When you have a simple vision, everybody is aligned in to it and every major decision is not a headache.
Do not worry about your competition.
This not only saves you on the stress levels but also helps in designing a clean product. Thinking that your product needs to be x++ to your competitor’s x is not going to work. You are chained to your competition and that is not where you want to be. Build half of what your competition is building. But do it exceptionally well. When Apple introduced the iPod there were enough mp3 players in the market. If it had decided to go one up its competitors, the iPod would have had radio, more buttons, more storage, better audio quality etc. But Apple took the other path. It cut down on the features, file formats supported, buttons, had a poor audio (it still has) and what features it supported, it did exceedingly well. It wiped clean the mp3 player market. Which would you rather buy? An iPod or some fully loaded mp3 player?
Freeze out the requirements after the design phase.
Follow this rigorously. Because adding new requirements after some stage creates more problems than it solves. This is one of the main reasons of how you lead up to bloated software. When you make changes after design, the dependencies between each component grows exponentially. In the end, you would hack everything to just keep it working leaving behind a mess of code. This might not be easy when your boss comes in and tells you to add another feature. But the dependencies in the system need to be explained and the consequences of such action carefully considered.
If there was one aspect that decided the success or failure of a project, it is communication. How you communicate with the various stakeholders is critical to smooth functioning of your development process. Find a way that is good and comfortable for your team. Use whatever tool your team is comfortable with. Use whatever standard. But get it right. When you get communication right, half your problems go away.
Bloated software is uncool.
No one likes bloated software. Neither the developers nor your users (Adobe Acrobat, Windows Vista etc.). In fact, it is much harder and time consuming to build clunky software. Instead, try taking the simpler route. Keep your interfaces, UI, modules and interactions simple. Let the user feel light when using your software. Cut out all that bloats your software. When 37signals built Basecamp, they wanted to keep it simple and implement only the essentials. This way they left out features like fancy charts, to do lists and multi-level messages. The result was a light and well-designed project management tool. This helped them kick ass of all other tools in the market. Posterous took the same route against Wordpress. They offered less features, but what features they offered, they did it very well. They made it very simple for the users to use their platform. Now, Posterous has risen up as one of the best blogging solutions available in the market.
Do not sweat over small stuff.
It is the small stuff and not the big decisions that always halt a development process. What font does your header needs to be in? What is the spacing between your menu items? What pictures do you need to include in your presentation? These questions not only delay the process but also tend to hurt egos. Do your team a favour. Just make the small decisions and move on. You can worry about the small stuff later.
It is good to have buffer time.
Humans are usually bad at estimating the completion time of a task. Having a buffer time prepares you for situations unexpected during the development process. Team lunches, bonding exercises, server crashes and holidays are some events that cannot be estimated well in advance. No matter how long or how short your development cycle is, you need to have some kind of buffer time.
Meetings are a waste of time.
Meetings are so toxic that just mentioning them gets a person to yawn. You schedule a meeting for abstract concepts and even for the small decisions. You even have meetings about meetings. You end up not only wasting your time but also collectively the time of others. Instead discuss it quickly over an email or IM. Meetings are all about talk rather than doing. But if you still need to schedule meetings remember to have people think about the problem/situation much in advance and mail the action steps to the organizer. Then you can schedule a 15 min meeting to decide (for sure) on an action step. This should work well than your normal one hour meeting.
Create prototypes often.
Prototypes let you get something working out of the door. This is not some hypothetical document/idea but instead working software. You can use it to evaluate against your requirements and use cases. The prototype need not be the finished product. It can be ugly, disorganized and hard coded. When you have a prototype, everyone’s thinking is aligned to it. No one can think two ways about it. Result is that you bring everyone on the same page. Have you seen the above illustration?
Well if they had created prototypes often, the result would not have been such a screw up.
Do not try to make perfect software.
Because then you will never ever ship. Try to release your software often. You can iterate based on your user’s inputs. Google perfects this step very well. They do not wait for the software to be perfect. Instead they open it out to the users and build it from there. If you wait for the perfect product, the market is going to pass you by. Remember, this does not mean you need to ship crap software. It is just that you get out a good enough product and work from there by iterating. Why do you think Fortune 500 companies have huge marketing departments?
Write own test cases for your code.
Because this helps you think clearly about what your code should do. It not only offers more than just simple validation of correctness but also drives the design of your program. You get to think about how your end users will use your module and how it interacts with the rest of the system. You are doomed if you think test cases should only be prepared by the QA team. For example, if you are coding up quick sort, first come up with test cases like empty array, array having one element, array having negative elements etc. Test cases help you form the structure of the program before you start to code. And this is always a good thing.
This might sound cliché, but having a good team is very essential to building a great product. No one can do it all by himself. Team members need to support each other to keep the development process moving. Accept failures can happen. Let your team members take bold risks. Give them space to do their magic. Do not culture the habit of pointing out mistakes. Instead culture a one of learning from mistakes. Creativity can only occur when people trust each other. Software development is as much a people problem as it is a technical one.
You don’t have to be stiff and serious when you are developing software. Run wild. Have fun.
If you read this far, you should follow me on twitter.
Also feel free to follow my projects on github.