Need text? Hire a Writer

To help create the document I mentioned earlier about the merits of custom software development, I hired a subcontract writer. The only typing I did was a bit at the start and perhaps a half-hour of editing at the end; all the rest of my input was in the form of spoken-word audio recordings, which I find fast and easy to create.

A critical factor in making this worthwhile is the categorical difference between a writer and a transcriber; I’ve used transcription services with excellent results, but a transcribed talk is far different in form and polish, than purposefully written text. The process was roughly like so:

  • I posted an ad on Craiglist to find a technical writer
  • I wrote short notes/outline of the topic
  • I recorded an audio ramble of my ideas for the content
  • Writer sent me draft #1, organizing my ramble in to a coherent form
  • I recorded audio feedback
  • Writer sent me draft #2
  • I recorded audio feedback
  • Writer sent me draft #3
  • I made a bunch of edits, and posted it

This worked out well, in several ways. The first, minor payoff is that it took a bit less time than just writing it myself. In retrospect it was only a minor time savings; if I had just sat down and wrote it all myself in one go, I could have finished in a handful of hours.

The second payoff was much larger: although I could have theoretically done it all myself, most likely I would not have done so yet. My personal threshold to get started and keep the process moving was much lower. Engaging assistance transformed an idea for what could happen, in to a process that did happen.

The third payoff is that this process is another useful tool in my toolbox; there is a big difference between know that I could use such a tool, and having actually done so.

Thus, I consider the experiment a success, and will almost certainly use the same process on more projects.

Buy vs. Build

A while back Joel Spolsky wrote about “Five Worlds” of software development. Over at Oasis Digital and elsewhere, I’ve been living in two of them:

  • Custom, internal software that we develop as consultants.
  • Commercial software that we develop at our expense, then sell licenses.

As a result, I’ve been thinking a lot about the relative advantage of each, from the points of view of software developers and customers. A portion of these thoughts, those on the merits of custom development from the customer perspective, are in an article (PDF) on the Oasis Digital web site.

There is a story behind how that document was created, and I’ll tell it in another post.

Start with a Prototype

I have often given the advice to start each project with an end to end working first draft, also known as an evolutionary prototype, and sometimes I have even followed this advice myself. My own projects have been most successful when following it, such as in three projects that come to mind:

  1. A 6+ year project, with a team of developers. In month 3 it was deployed to production, meeting real needs.
  2. A 4+ year project, with a team of developers. In month 2 it was deployed to production, meeting real needs.
  3. A 10+ year project, initially just myself but later with a small team of developers. In month 1 it was deployed to production, meeting real needs.

On the other hand, most failed projects that I am aware of had been slated from the beginning to not deliver a working system until late in the schedule, and ended up not delivering at all.

The traditional software development plan for a typical enterprise forms-database-rules-reports application looks like this:

  • Planning and design
  • Implement schema
  • Implement infrastructure
  • Implement admin/setup features
  • Implement core features (transactional data)
  • Implement reports

This waterfall model is a great way to think about software. Think through your requirements in depth at the beginning, and write them down in a coherent form. However, this is generally a bad manner (specifically, a very poor order) in which to write software.

Thanks to the agility movement, many teams are now using iterative, incremental approaches. Unfortunately, it is common nonetheless to lose some of the benefits of agility by laying out a set of releases with features/work in approximately the traditional order.

The solution, espoused by the Extreme Programming movement but rarely executed, is to start at the very beginning of a project, with building an end to end, first draft, working prototype system. This then grows slowly over the life of the project in to the finished product (i.e., it is not a throwaway prototype). We take this approach at Oasis Digital, and generally require it of our subcontractors also.

Development proceeds in a way that we create a working, end-to-end system with minimal features, very early in the work. For example, on a typical forms-database-rules-reports project, after a few days of work, we have:

  • A little bit of schema, just enough to support a small subset of desired features
  • A few screens, with very few features
  • A report or two, again with very limited features
  • Placeholders for some other screens and report, to allow the beginnings of the desired final application flow to appear

Then as the work proceeds, every week (or less) we can deliver a working system with a few more features present.

But this is impossible on my project!

The question is not whether this approach is possible; rather it is to what extent it can be done on each project, and what can be done to make it possible? The primary tool is imagination, in selecting a small subset of the desired feature set which plausibly works end-to-end.

For example, perhaps you are building a CRM (customer relationship management) system, one with thousands of features, 200 database tables, 450 reports, 85 screens, etc. How could you build a working system in the first week? Start by reducing the system to be its bare essence of companies, contacts, and interaction history.

A second example is a time tracking system with elaborate rules, reports, approval mechanisms. For the first draft, discard most of that and create only the ability to add a user (forgot edits and deletes, forget most of the fields), to enter hours for that user (forget approcals), to see a screen with those hours (with the simplest possible layout), and export a data file with those hours (any data file format, forget XML for now).

A third example is a trouble ticketing system. For the first week, make a way to add a ticket, a way to add notes to a ticket, to see a list of tickets, and to close a ticket. This could readily all occur on one screen, with only a few buttons. Its schema could consist of three tables: user, ticket, note.
A fourth example is a system which will write checks. In the very first week of the project, make it write a check. Dummy-out as much as needed to make it achieve this core goal.

Just Do It

Certainly there are plenty of problem domains where this advise doesn’t readily fit. But don’t be too eager to make that claim. By finding a way to deliver a working system early, we eliminate the risk that the project will never deliver anything, and we make progress and value visible (continuously) to whoever is paying for the project.

On the Job Training

I recently heard from a developer who worked on a project here for about one year, several years back. I won’t name or quote him directly; the essence of his message was:

  • He learned a lot during that year.
  • This learning was a turning point in his career.
  • What he learned has proved lucrative.

Of course it feels great to receive a message like this, but beyond that, it got me thinking about on-the-job training at Oasis Digital. We don’t have a formal training process. Rather, opportunities (and pressure) to learn and improve are woven in to our daily work. Described in coarse terms, a typical workflow for a developer (“You”) starting out on our projects is:

  • You write some code (or other work product).
  • Tech lead and other developers (sometimes including me) complain about it. This takes the form ideally of constructive criticism.
  • You improve the code.
  • More criticism.
  • You improve the code more, resulting in code that essentially works.
  • Tech lead revamps and refactors it mercilessly, explaining what was changed and why. Note though, that at this stage the changes do not require justification.
  • Tech lead sends developer a list of things to further improve.
  • You improve the code.
  • The code is now good enough to go in to the project.

It turns out that this process is a very good learning experience, if you are willing to take feedback. It can be hard to hear feedback, especially if its essence is that that your work product is not all that great. Yet the computer is merciless, it does not care about your feelings. The end customer does not care about your feelings either; both care only about correctness and quality.

I started out writing bad code. Having written many lines of such code, I now, somewhat regularly, write good code… though I am certain there are plenty of better developers out there who could find much fault in it. Writing bad code and accepting criticism of it is on the path to writing good code. Is it controversial to observe that a lot of software is quite bad? If so, that’s fine; I mostly agree with Steve Yegge’s observation:

By way of setting context for today’s blog, I’ll summarize everything I’ve ever written to date in one sentence: I think most software is crap.

By accepting that most software is bad, you can get on a path to make yours better. It turns out that working on our projects gets you a lot of coaching and training; and instead of paying for these things, you get paid. For the right kind of developer, I think this is an important part of our value proposition and compensation.

Playing to Win, Going Beyond the Call of Duty

I’m writing this up as advice to a rhetorical “you”, but it’s really written to a younger version of me.

Imagine that you are working on a project for a customer (or employer), who has a weekly or monthly budget limit. You are paid by the hour, for up to N hours per week; or perhaps you are paid a salary for full-time work, nominally 40 hrs per week.

You want to work on the project more hours than your customer will pay for. For example, maybe your customer can afford only 20 hours per week, but you have more time available that you’d like to spend on the project.

The most obvious path is to simply not work any more than your customer will pay. Go do something else unrelated instead, perhaps not even computer-related. This approach appeals strongly from a work-life balance perspective, and also has a “tit-for-tat” appeal along the lines of “I refuse to do anything that would benefit my customer unless I am being paid to do so”. However, it is a very bad strategy. Do not let your customers’s budget stop you from growing your skills and building something great.

A second path, at the other extreme, is to work all you want on a project, regardless of how few hours you are paid for. Simply don’t bill for the extra hours. This is an easy answer, and in spite of its appeal from my current perspective (as an employer and customer of software development work), I don’t recommend it. It will give your customer an erroneous indication of your productivity level, causing future problems for you (how will you live up to this apparent but false productivity in the future?) and for your customer (whose estimates and schedules will be fed by false data).

I recommend a path between these two extremes, a strategy by which you can do work that benefits you and your customer, now and in the future. Work the hours you bill, directly on your customer’s project. Then, if you have extra time available (that you haven’t filled with other, paying work), work as much as you care to, past those hours, on related activities that indirectly help the project and help you grow:

  • Read about the development tools and technologies you are using. (Learn by reading.)
  • Read about the project problem domain.
  • If your customer project uses a DBMS, read about and experiment with that DBMS.
  • Try another DBMS; port the customer project to this other DBMS. Even though the customer doesn’t need it, you can nonetheless learn a lot from the experience.
  • Build an additional feature that your customer did not ask for (yet); the offer it to them if they want it. By the way, this is a great time to learn to use a powerful source-control system to manage a long-lived branch with such a feature.
  • Start a second, sample project, which uses some of the same tools as your customer project. Learn by doing. Experiment on this sample project, practice using the tools. Try out options and feature of the tools that you haven’t needed yet on your customer project.

To me, this is a strategy for “playing to win”.

More About the Sample Project

By the way, the notion of a second, sample project is very powerful, for reasons far beyond your current project. Be careful to keep the real project code completely out of this sample project, and you will end up with a very valuable artifact: a working piece of software, built with tools you know well, which you own. You can use this project to help get future work, by offering it to future customers as a work sample, and by posting it on your web site to show (rather than merely proclaim) your expertise.