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|
|1||Decide what to cook and find a recipe||Decide on a project and get a general idea for how it will work|
|2||Buy the ingredients||Choose your tools|
|3||Start the first step of the recipe right away, without reading the recipe first||Dive into writing code without making a complete design|
|4||Locate, chop and measure ingredients as you go while trying to not let anything burn||Start writing or finding the various components of the project when you realize you need them, often moving between several tasks|
|5||If an ingredient is required that you don't have, improvise with a substitution or go without||If 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|
|6||Leave a pile of dishes in the sink, half-used ingredients sitting out, and dirty countertops that you have to clear up after||Leave 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.
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.