Software is like cooking

In virtually everything to do with software, there is often some kind of metaphor used to describe it. Often, these are taken from the building or manufacturing industries (even some of our titles are taken from these: Architect, Engineer, etc.) and many times different metaphors seem to suit different situations better. If you haven’t guessed from the title, I think the best metaphor for software is actually to compare it to cooking. I’m still trying to find a situation where the metaphor doesn’t work (and sometimes its a bit of a stretch), but here are a couple of examples.

Your software team is made up of developers (cooks) and often headed up by a manager (chef de cuisine) sometimes with one or more technical leads (sous chefs). They produce applications (dishes) or libraries (portions) that are used to create a larger product (meal) that form part of a suite (menu).

Sometimes the applications have the same implementation underneath, but look different to the end user (re-arrange the food on the plate) or even feel different (change the garnish or sauce). Sometimes the application will work the same on the outside, but have a different implementation underneath (the recipe for any given portion might change but the meal will still be the same).

Different people are good at different areas. For example, someone might have great knowledge in developing the GUI (saucier), someone else is good with databases (pastry chef) and so forth. Some people will specialize in Java (Italian) or .Net (Chinese), and within those might have a lot of knowledge about for example Servlets (pizza).

We have design patterns (recipes) that make it easier for people to produce good quality apps (dishes). If you need to write an app (cook a dish), you can start with what you know. You know that a web app (pizza) will need some HTML (tomato sauce), maybe some JavaScript (pepperoni) and of course a web server (bread) and some kind of CGI mechanism (cheese). Of course, once you dig into things a bit more you may discover that your customer really wants a doughnut :-)

Self-development Window

MJ recently blogged about identifying one’s own strengths. I thought it would be useful to share a tool that I’ve used over the last seven years as a herder of cats (read: software development manager). I call it the self-development window (or the career development window, as I often use it for that purpose). It looks a bit like this:

Self-development Window

(The astute among you will notice some similarities with SWOT Analysis).

To use the window, just fill in something in each of the first three boxes. Don’t worry about filling them in in order, just put them in whatever order occurs to you.

Strengths

This area includes the skills you use on a daily basis, or that people come to you ask questions about. Often (especially with software folks) we think in terms of technical skills – i.e. the skills where we actually do something or produce something, so don’t forget the so-called softer skills: communication, planning, leadership, etc.

Areas for Improvement

Things that you want to get better at. This might be particular skills that you want to learn, or some area of other knowledge you want to acquire. Many people find that they want to improve in many things, so sometimes this area gets crowded – don’t worry, that’s normal.

Goals

Goals differ from Areas for Improvement in that they are things that you can check off to say you’ve accomplished. For example “Learn to program in Objective-C” is an Area for Improvement, but “Write a commercial app in Objective-C and sell a copy to someone I don’t know” is a goal. Also, goals tend to include things that are much longer in time span than Areas for Improvement – e.g. “I want to become CEO of a company with more than 100 employees”. Make sure it’s easy to measure that you’ve accomplished them – ‘checkbox’ style items work best in my experience.

Tasks

Once you’ve finished with the first three sections, put a time frame on the Tasks section (I usually say three months) and then put specific tasks in there that you can accomplish in the next three months. These tasks must help you improve in one of your Areas or help you achieve one of your goals (or both!). Often you use your Strengths to help accomplish these tasks.

OK, so now what?

I get each of my team members to do this every three months. Then every two weeks we have a chat about how things are going (those chats are not solely about this Window, but it does come up – my job is to help them achieve all their tasks) just to make sure there aren’t any roadblocks and that all the tasks still make sense. If you’re doing this for self-development, it’s probably worth looking at this every week to see if you can accomplish any Task in the week, or work on it. Make sure you:

  • check off any Task or Goal that gets accomplished
  • do the exercise again after your allotted Task time elapses (i.e. every 3 months in my case)
  • move Areas for Improvement into Strengths once you’ve learned what you set to learn
  • look back over your Windows for the year to see what you’ve accomplished and to help motivate for the next year

I’m not sure if the form-factor of a Window actually makes any difference: it evolved from my need to write it all on a whiteboard. I do think it’s useful to have all four areas up on the board at once because sometimes your mind goes blank and writing other things helps jog your memory.

Green fields and how to sow them

Here’s the scenario: you’re writing a green field web application. This application will be used to power more than one e-commerce site, which means that it must be easily tailored. You can use any toolset you like, and the requirements are fairly standard (e.g. exporting data to CSV, modern UI, payment gateway, etc.). What do you choose?

  1. Off-the-shelf e-commerce engine
  2. Open-source e-commerce engine
  3. Build your own

So, it seems you’ve got three options (anyone think of a 4th?). Of course within each of these options there are any number of competing solutions, especially in “build your own”, where you could potentially use any language, web server, etc.

I think with any software developer, the preference is to build one’s own. That way you get ultimate flexibility and intimate understanding of the code, which makes it easier to expand and customise. The downside is that you have more work up-front in order to get running.

Off-the-shelf (i.e. commercial) software tends to have a lot of features that your accountant and fulfillment department would like, and often gives you the ability to customise using one of a few popular languages or their own pseudo-language. The real advantage is that you can have a store quickly, or so you might think. Often, shoe-horning your data into their proprietary and closed-source format makes this option longer and more expensive than building it yourself.

All of which leaves open-source engines. You can be up and running quickly (like with commercial apps) but you have access to the source code if you decide you need to change things the way you want them. Potential downsides are lack of support and lack of particular features you might need (e.g. a particular payment gateway).

So, which would you choose?

From nothing to something: iterative app development

1. Prove it works

write the simplest code possible to show one thing working end-to-end

This can be as horrible and hackish as needed. I regularly hardcode things like URLs, integers, strings, file names/paths: whatever is needed just to show that the idea works. E.g. for Rickshaw, I started off by always sending a file called rickshaw.png, which just got removed and replaced by a URL – the URL in the e-mail was hardcoded to be a reference to http://localhost/~aidan/rickshaw.png, and I happened to have the file in that directory. The whole workflow appeared to work, even though none of the upload magic was there. I proved out two concepts though:

  • that attachments could be manipulated after sending
  • that the resulting e-mail still made sense

2. Add to it

write the next most important bit simply, then test it all

This can be harder than you think. Not the writing, but choosing what bit is the next most important. For me, I wanted to have that file be written dynamically. The important thing is to keep it small – do it, test it and be happy with it. Some things lend themselves to automated testing: some don’t. I’m a fan of test-driven development, but I don’t get hung up on ensuring coverage – look at Microsoft Windows Vista: excellent automated test coverage, crappy user experience. Test manually where it makes sense, and automatically where needed.

3. Repeat step 2

You go from your tasks being “remove hardcoded URL and replace with URL generation code” to “Add application icon” and “Build website to sell app”. One step at a time, doing the most important thing at any given time.

Rickshaw had no user interface for quite some time – it was just a plug-in that was copied from the command line. Eventually that was good enough that a UI for configuring it was the most important thing. Then a button that tested the configuration before using it. Then some code to install the plug-in. License keys. Usability enhancements. And so on.

None of this is new or original – it’s all common sense, especially if you’ve worked in an agile development team before. The great thing about working this way is you see results early on. I had a working prototype of Rickshaw which did “uploads” to localhost (using NSData writeToFile:atomically) within a week, and real uploads within three weeks. The downside is that you feel very close to finishing at an early stage.

If you consider the entirety of what’s needed to build an app as being 100% of the effort, I’d lay out the effort required for different parts as something like this:

  • Hack to prove concept: 5%
  • Prototype to prove hack: 15%
  • Making prototype robust: 30%
  • Getting it ready for users: 50%

Open source projects are one of the first three stages (corresponding roughly to ‘alpha’, ‘beta’ and ’stable’ projects). The last stage takes just as long as the first three, and it’s the reason why commercial Mac apps (in particular) are better than open source apps for Linux – as much time has been spent getting the application to work well for users as has been spent getting the application to work for the developers.

If you’re developing an app for any platform, ensuring you spend the time in that last stage is what will make your work stand out.

Ironcoder 7 date set

The 7th Ironcoder contest was announced today (for some definition of today – damn those pesky time zones). I think this year I actually feel confident enough to take part, even if I accomplish not very much :-) For those who have no idea what it is, each contest selects a theme and Mac OS X API, then gives you 48 hours (real time) to write an app that has both theme and API centrally featured. Check out the Ironcoder site for more info, or take a look at the entries for Ironcoder 5.