In my career I have had the pleasure of working with several successful software teams on a variety of projects. I have also had the opportunity to mentor or review more than a hundred software development teams. I have written programs for Windows, Mac and Unix, Android and a bunch of Web delivered apps. At Netscape I was part of a small cross platform development team that wrote Netscape Navigator which at that time was the most used application in the world.
In this article I would like to concentrate on platforms and tools. Platforms and tools are one of the least understood or appreciated since they technically focused and most engineers don't get the opportunity to choose their tools. Whenever a new software project is created we make important choices about what platform and tools we are going to build with. I'm defining the platform to be the hardware and operating system and the tools to be everything else above the operating system.
Platform choices used to be pretty easy: Windows, Mac or Unix. When the world was 90% Windows, most software developers knew right away that they would be using Windows as their platform. Today we have many choices. Win, Mac, Linux, Android, iOS, Blackberry, Windows Mobile or HTML. Platform choices are usually driven by business reasons, but there are still technical choices to be made. For instance should you have a native windows or Mac app? Web applications are preferable for most since they solve the distribution and update problem, but they are not able to integrate seamlessly with the computer and can't handle long running background tasks. Music players are a great example of this. Lots of music companies have cloud players that run in the browser, but most choose to do a native app to support offline play and to have a fancy native UI. Mobile app companies also have an important choice about what platforms to support. Many mobile start-ups I see are just concentrating on their mobile apps, and not creating a web based experience. Unless they are a gaming company this seems extremely short sighted. Most of us live and work in a heterogeneous environment, so a web based experience allows us to work with a service no matter where we are. GoodReads and Google Maps are good examples of this.
I find that tools are the most difficult choices that we make at the beginning of a project. There are many different classes of development tools. These are just a few:
- Software language: C++, Java, PHP, Ruby, ...
- Framework: LAMP, Zend, Rails, Tomcat, ...
- Compilers & IDEs: G++, MSVC, Eclipse, XCode, ...
- Debuggers: GDB
- Databases: Oracle, MySQL, Postgres, Mongo, Cassandra
- Bug tracking: Bugzilla, Jira, FogBugz, ...
- Revision Control: SVN, Git, CVS, Perforce, ...
- Integration: Jenkins, Bamboo, ...
- Unit Testing: CppUnit, Google Test, JUnit
- Static Analysis: Lint, Klocwork, Coverity, ...
- Hosting: Equinix, Amazon, RackSpace, Google, ...
Many software tools are chosen on the basis of what was used on the last project. Familiarity is an important consideration, but should not be the only one. If we simply go with what we know we are missing opportunities to choose a tool that has advanced or is simply better suited to the current project. Here are some important criteria to consider:
- How suited is the tool to what I am building?
- Will the tool handle the scalability that I need?
- Supporting tools
How suited is the tool to what I am building?
To a hammer the whole world looks like a nail. Perhaps you really need a wrench or a screwdriver? If you are building a financial application, don't try to use a fancy new noSQL database. Use a good old fashioned conservative SQL database. If the type of app you are writing has a large portion of users using one tools set, you should probably choose that. Why try and build an Android app with MSVC when everyone else does it with Eclipse?
If you are building a web application for a small group, performance probably doesn't matter. If you are trying to be the next Facebook, you might want to think about how the tools you are using will scale up to millions of transactions and a big design team. Facebook is experiencing this problem in spades with their choice of PHP as a language. Their improvements to PHP are very impressive, but the effort could have been avoided by choosing a different language. Scalability also applies to team programming. Dynamically typed languages, such as PHP, Ruby and Python can be challenging for very large software projects since the functions are not explicitly typed. This makes it hard to detect software problems at link time and requires engineers to document their code in ways that are not enforced by a compiler.
Tool maturity is too often overlooked. I think this one should be easy, but I see start-ups making the wrong choices over and over again. If a tool isn't 99.999% stable, you probably should not use it. All of your time should spent solving technical and business challenges. If a start-up needs to spend time debugging their tools they are wasting valuable time and resources solving a problem that they didn't need to solve. How should you evaluate maturity? Past personal experience or a referral by someone you know and trust is best. Otherwise, look to see who else is using it. If you can't find a large list of other companies that are using the tool in a production environment, stay away. Even the most promising tool can turn into a nightmare if you make it part of your product and it starts to crash or otherwise misbehave. Building tools is hard, not just because they are hard to build, but because they are very hard to perfect. You need tools that work every time, not just most of the time.
This is probably the most important tool trait. Every tool class listed above comes with an ecosystem of tools that support it. With a database you need backup tools, profiling tools, monitoring tools, API libraries and documentation. New tools often look promising until you look under the covers and find out that it is lacking basic support infrastructure. Do you really want to find out after you go into production that your tool needs to be taken offline just to back it up?
Profiling and debugging tools are critically important and are often the last thing on a product road map. If you have ever experienced a critical performance bottleneck and have been without a real profiling tool you will understand how important a profiler is. How about finding a thread deadlock with a debugging tool that doesn't properly deal with threads? Memory corruption detection without a dedicated memory debugger? These are support tools that usually take many years if not decades to get right in a major tool class, but they are absolutely necessary.
Last but not least is the community of people that can support you for questions and problems. The absence of a strong community should be a huge red flag. Poke around and ask questions, make sure that there is still active development of the tool that you are choosing and lots of active users. Look for example code and places where people congregate to ask and answer questions. You will save a lot of time if you can draw upon the community to figure out problems for you. Open source libraries built for your tool can also make your job a lot easier. Plugins to support your other tool choices and layer in great product features.
Looking at the whole stack
Now that you have a framework for evaluating individual tools, you now need to go up a level and look at your entire tool stack. Almost all of the development tools you use will interact with each other so they need to be compatible. Want to use a Java based messaging framework but you use C++ everywhere else? Think again. Love that C++ static analysis tool, but you use Python? Sorry no dice. Your choices on one tool effect every other tool you will use. Make sure that you evaluate the whole stack before you commit to any one tool. Otherwise your one choice will likely dictate and limit all your other tool choices.
Current Experience Levels
Last but not least please be realistic about your team's experience relative to the tools you are choosing. It might seem like a great idea to use Ruby on Rails for your next major web project, but if there is nobody on your team that has any experience with Ruby you are probably going to run into trouble. If you already know PHP the benefits to moving to Ruby are probably overshadowed by all the mistakes that you will make learning a whole new framework. Remember that the end product is more important than the language used to express it and the user isn't going to care if you are using the latest and coolest technology to pull it off. Conversely, using a technology that very few people know, even if your team is very proficient with it, will limit your ability to hire new people in the future.
Apply this same methodology to support libraries as well
All of the points above also apply to support libraries that you will use in your product. Here are a few examples.
- Messaging frameworks
- General Utility libraries such as boost for C++
- Caching and proxy libraries and servers
- XML & JSON libraries
Look at all your tools carefully before you start using them. Make sure that they are all of the highest quality and maturity and that they come with the supporting infrastructure to handle the whole development process: Coding - Testing - Debugging - Profiling - Monitoring
Doing this will save you and your team countless hours of frustration relative to less mature tools.