Tuesday, March 3, 2009

The keys to successfully delivering software

I have been developing and delivering software for over 10 years now and I have learned a few things along the way. I am not the smartest developer, the most elegant engineer or a hardcore software design geek. I have however had a good deal of success delivering software that meets business requirements on time and learned what works and what doesn’t along the way. In this post I will share with you what I have learned that works well and what routinely causes failure.

Extremes lead to failure

Let me warn you in advance of a theme that you are going find throughout this post; avoid extremes. This is a general principle in life that applies heavily to successful software development. For example, there is nothing wrong with alcohol in moderation. However, if your goal in life it is get hammered at any possible opportunity you are going to watch your life go down the drain. Cheeseburgers are great, they are yummy and one of man’s greatest inventions. However, if you hit up In-N-Out every day for lunch and throw down a couple of double-doubles you aren’t going to be a happy camper after a while. The same basic principles apply to successfully delivering software, you need healthy moderation in all areas of the process.

Cut out the cancer

You need to have a good engineering team. Now the definition of a good team can very widely, but here is my take. You need a group of engineers that are good at what they do, have interpersonal skills, can communicate, check their egos at the door and all share the common goal of delivering quality software that meets the business needs on time. If you have engineers on the team that are a cancer to your success you need to figure out how to deal with them rather than avoid them or mitigate them and hope the problem goes away.

One of the common engineering cancers is the apathetic engineer. This is the engineer that comes in, does just enough not to get fired and looks for every opportunity to do anything other than work. The apathetic engineer will drag down those they work with and will make the rest of the team of engineers who are working hard angry.

The other common engineering cancer I have seen on teams is the ego engineer. This is the engineer that feels they are the apex of software development and no one before them or after them will ever be as good. The ego engineer is a poison to the team and most of the other engineers will avoid working with this person like the plague. They aren’t part of the team, they are an island and almost always are more talk than substance.

Your engineering team needs to gel well, with strengths and weakness complimenting each other. It is also very important that your team enjoy working together and respect each other. If your team hates to work with each other and there is disrespect within the group they will not perform well. Remove any cancer that exists and when you add new team members make sure that they are the right team fit.

Success Starts with good requirements

You can successfully deliver good software on time without good requirements, but it isn’t easy. Again, you don’t need an extreme here. You don’t need your marketing/product group to spend months and months and months analyzing requirements and debating over little nuances only to deliver the best set of requirements ever written two weeks before the year long project is due.

On the other end of the spectrum are back of the napkin requirements. I had a product guy once that would go to bars, get drunk and then write out all of our “requirements” on the back of a napkin while he was hammered. He insisted that we should be able to successfully build any complex application with no more input that what he was able to scribble on a napkin while inebriated. As you can imagine, this end of the extreme didn’t work out too well either.

You don’t need perfect requirements, but you need good requirements. Good requirements are well thought through, documented well enough that engineers can understand what the business needs are by reading them and have actionable requests. Wireframes, mockups and user experience scenarios are also very helpful to put into requirements.

don’t under or over engineer

Ah, now that you have a good team in place and you have some requirements you can work with here comes the fun part, actual engineering. Unfortunately it is still pretty easy to fail the actually software development part of the process even if you have a good team and solid requirements. Successfully delivering software from an engineering point of view requires that engineers be utilized effectively and over or under engineering is not allowed to be part of the process.

Under engineering is otherwise known as hacking or spaghetti code. This is where your engineer’s only concern is getting the feature “done” and they have no concern for how it is done. Common excuses here are that “the requirements are changing all the time”, “we just had to get something in there”, “lets just get it working and refactor it after the fact”, etc., etc., etc. Hacking crappy code together never works out well. Even if you can hack features in to a working state, this approach will lead to tons of bugs and doesn’t create a foundation that you can build upon for future features and enhancements.

Over engineering is a little bit trickier than hacking. Hacking is generally considered “bad” by most engineers and you won’t get much push back if you bring it up as a problem. Over engineering on the other hand is commonly accepted and viewed as good work because the theories and design being applied are all generally good software development. The problem here is that if you spend all of your time writing the most awesome, perfect, beautiful, slick, lovely, sweet, hotness widget you will probably never deliver anything at all, let alone on time. Software needs to be designed well, but if it is over engineered, overly complex and plans too far ahead in the future it is like spending the time to lay the foundation for a skyscraper when all you need to build is a single story house that you might want to add a room on to later on. Over engineering can be just as big of a problem as hacking because at the end of the day you still don’t end up with that you need to be successful.

Balance is once again the key to success. Don’t hack, but also don’t spend so much time trying to put together the ultimate software design for what you need that you don’t get anywhere. Come up with solid designs that are flexible and are forward thinking, but keep them within the scope of the requirements and apply KISS (keep it simple stupid) as much as humanely possible. Make things only as complex as they need to be, comment your code and keep on alert for engineering scope creep as well as project scope creep.

How does this apply to .NET development specifically?

These basic principles apply to successful software development in any language on any platform. However, from what I have seen .NET development is specifically prone to problems with under engineering. Because Visual Studio is such an awesome IDE and because Microsoft makes so many of the tasks so easy to complete in ASP.NET there is a tendency for developers to rely on the wizards and just brute force something that works into place. ASP.NET developers need to intimately understand the platform that they are developing on as well as understand best practices for general software design.

I hate to say it, but a lot of the problems come from software developers that worked in previous Microsoft frameworks such as Visual Basic who “update” their skills by opening Visual Studio 2008 and starting to code. The .NET framework is vast and if you want to write successful software in .NET you need to understand a) solid OOP software design principles and b) the framework itself. If you don’t understand solid OOP design principles, you need to take some classes or update your knowledge with some good books to get the basics. If you don’t understand .NET, I would recommend that you read some of the Intro to the Framework books and take one of the foundational Microsoft tests. The tests aren’t perfect, but if you study for them and pass them I guarantee you will come out understand the .NET framework better than most.

How Do I proceed?

If you read through this post and identified some area(s) that your company is currently struggling in, the fix probably won’t be quick or simple. You are going to have to put together a plan of what needs to change and how it should change, get buy in from the right individuals and then slowly implement process changes or team changes that will fix any issues that you identify. It is hard work to get past process or team problems, but well worth it when your software cycle becomes easier and is successful on a frequent basis.


kick it on DotNetKicks.com


Anonymous said...

Good to see a software developer/engineer identify good requirements as one the keys.

And a high volume can be produced in a short time, see www.iag.biz .

Anonymous said...

Well said. Another key aspect and challenge of delivering successful software is planning the deployment. Its like being on a sports team and practicing the plays - you still need to run through the scenarios when you new plays don't fall through. That seems to be the place where I see most stress happen. When the developing is complete and looks awesome, but nobody tests properly or discusses implementation and something blows up, it is really a challenge to see who/what/when/where/why it will get fixed and prevented in the future.