Almost everyone who has ever written code will have, at some point, started writing without a plan for what behavior that code is ultimately supposed to exhibit. Often, these early drafts are messy, but you tell yourself you’ll clean them up. Before you know it, late-stage attempts at code clean-up break something, and bloated code littered with TODOs makes its way into the finished product.

What can be done? As it turns out, inspiration from unexpected sources can reinforce best practices.

Hats off to French chefs

Mise en place is a philosophy that began in French kitchens, but is now the industry standard for professional chefs around the world. The phrase roughly translates to “everything in its place,” and it boils down to a couple of basic rules: preparing your tools and ingredients before you start cooking, and cleaning as you go. This method mass-produces delicious meals quickly, efficiently, and even elegantly: A master chef in their element is an artist at work.

So how does this relate to software development?

Everyone starts somewhere

Many self-taught cooks start off in the kitchen making common mistakes that are very similar to some of the methods used by early developers:

 "Unprepared" Cooking"Unprepared" Coding
1Decide what to cook and find a recipeDecide on a project and get a general idea for how it will work
2Buy the ingredientsChoose your tools
3Start the first step of the recipe right away, without reading the recipe firstDive into writing code without making a complete design
4Locate, chop and measure ingredients as you go while trying to not let anything burnStart writing or finding the various components of the project when you realize you need them, often moving between several tasks
5If an ingredient is required that you don't have, improvise with a substitution or go withoutIf a tool is required that you don't have or part of your plan no longer seems possible, find a workaround or skip that idea
6Leave a pile of dishes in the sink, half-used ingredients sitting out, and dirty countertops that you have to clear up afterLeave incomplete (or absent) testing and documentation to be done at the end, as well as bloated code to clean up after

What do amateur cooks and inexperienced developers have in common?

This method is more of a hopeful experiment than a replicable science. It can create great-tasting meals or code that works as intended. But most of the time, your dish, or application, won’t reach its full potential. It also leaves a mess to clean up afterwards—and good luck describing your methods to someone else, or even remembering what you did yourself.

For a lot of developers, every project results in these twin feelings of exhilaration at the creative process—yay! It worked!—and the underlying stress of knowing any shortcuts you took, or waste caused by inefficiency and lack of discipline, might come back to haunt you later.

Going pro

Like mise en place, test-driven development is a philosophy that provides guidelines for a better way to create high quality code you’re proud of, that’s built to last, and that other developers can immediately understand and appreciate.

The steps of TDD are simple: Before you write a single class of code, think about how exactly your code should behave, and write the smallest possible test for it that will fail. Confirm that it fails, and then write just enough code to make the test pass. Once you’ve confirmed that your code passes, move on to writing the next test. Refactor as needed if new code has introduced duplications or other problems, and repeat again from step one. And voilà: TDD by design results in clean code that is already documented and greatly reduces the time you’ll later spend debugging.

By following this philosophy, you will be on your way to writing lean, focused, effective code. Your method will be easily understandable for anyone else who reads it, like a well-written recipe. The finished product will be predictable, efficient, and at much lower risk of breaking, and it should do exactly what you intended it to do.

Practicing test-driven development will make life a lot easier for anyone else who ever needs to read or use your code later, whether that’s your teammates, the OS community, or future you. There’s a reason all aspiring chefs learn patience and discipline in culinary school: it may take time, practice, and careful planning, but it works.

Edit: Looks like someone else has made the same connection! Check out Jacob Bogart’s thoughts on the subject here.