In the past, programming was an activity based on assembling low-level instructions using a small numbers of structures: there were loops, conditional statements and function calls. Systems were built through the application of relatively few patterns at different scales. Even the design was very simple: Dataflow Diagrams (DFDs) consisted of only processes, data flows and data stores; Entity-Relationship Diagrams (ERDs) had only entities and relationships.
Today, programmers work on a much higher level of abstraction, applying the mechanisms of Object-Oriented Programming, adopting Design Patterns, reusing sophisticated class libraries and extending powerful frameworks. Besides writing new code, developers are also expected to perform parallel tasks such as Refactoring and writing Unit Tests. The design phase requires a great diversity of complex diagrams, like the ones defined in UML.
The consequence is that today developers are making very important decisions at each step of their work. They must choose between composition and inheritance. They must decide if a class in a library is appropriate for their needs. They must analyze the trade-offs involved in the adoption of different Design Patterns. They must plan how to Refactor their code and how to assure good coverage through Unit Tests. Many of these decisions are not really programming issues in the traditional sense; they are in fact design decisions.
Then, if programming today can be defined as a series of high-level decisions, the question is: How can we assure that the developers are making these decisions effectively?
A recent article at the New York Times addresses the issue of Decision Fatigue. The article mentions several researches that prove that people who are required to make many decisions become mentally exhausted, until they reach the point in which they are no longer able to make effective decisions. In its words:
“No matter how rational and high-minded you try to be, you can’t make decision after decision without paying a biological price. It’s different from ordinary physical fatigue — you’re not consciously aware of being tired — but you’re low on mental energy. The more choices you make throughout the day, the harder each one becomes for your brain, and eventually it looks for shortcuts, usually in either of two very different ways. One shortcut is to become reckless: to act impulsively instead of expending the energy to first think through the consequences. The other shortcut is the ultimate energy saver: do nothing. Instead of agonizing over decisions, avoid any choice.”
One concrete example is Copy-and-Paste programming. It is very common for a programmer to need a piece of code that is very similar to something he has already written in the past. The best way to reuse this code would be to Refactor it so that it can be shared, but this involves many decisions about how to do it correctly without breaking existing code. Thus, if the programmer is tired, he will probably just copy-and-paste it, because it is the most impulsive action and requires minimal mental effort.
The problem of Decision Fatigue is particularly important when the person needs to make trade-offs. As we know, most design decisions require evaluating different options and analyzing their advantages and disadvantages. In the words of the article:
“Part of the resistance against making decisions comes from our fear of giving up options. Once you’re mentally depleted, you become reluctant to make trade-offs, which involve a particularly advanced and taxing form of decision making. To compromise is a complex human ability and therefore one of the first to decline when willpower is depleted. If you’re shopping, you’re liable to look at only one dimension, like price: just give me the cheapest. Or you indulge yourself by looking at quality: I want the very best.”
I believe that every developer has experienced this single-dimension reasoning, making decisions that appeared to be good at the moment, but then proved to have some very serious negative consequences. For example when a programmer implements a new data structure and forgets about the need to keep it synchronized in a multi-threaded environment. Sometimes these bad decisions are just discovered when the system starts exhibiting some very strange bugs and unexpected behavior.
So, to assure that developers are making decisions effectively, we must either avoid Decision Fatigue or provide ways to recover from it. The article recommends consuming sugar, for example in the form of soft drinks. I would recommend making a short break whenever you feel tired, and spend a few minutes in some activity that does not require much mental effort. And have a Coke.
The most important conclusion is that, if a developer is making important decisions, he should not be required to work long hours. It is absolutely impossible for a human being to continue making effective decisions after many hours of work, no matter how smart or experienced he is.