The Importance of Nothing to Do
In a developer environment, most time is spent pushing to meet deadlines, implementing changes for the next iteration/sprint/release, and analyzing issues that have arisen from the previous release. In some cases, the perspective of management is that developers need to be overloaded to encourage them to look for a more efficient solution; in others, executives feel that developers have quicker problem solving skills to where they are expected to find specific and flawless solutions to somewhat vague requests; still others, management is well meaning, but there are simply not enough developers to handle the workload, and a programmer becomes swamped in work. Regardless of the motive, there is that shining, albeit rare, moment where a developer, or an entire team, has a very slow workday.
This is not cause for concern with executives and project managers; this time is invaluable if used properly. The following points discuss invaluable processes that can take place with the development team when workloads hit "low tide".
Discuss Flaws, Flow, and Future
I worked at a company that once had employees look at the ups and downs of the week, then plan for the future, recording it at the end of every week in something that management was allowed to look at. I am certain that the purpose was for the executives and managers to get a snapshot of an individual's performance and progress, but in the end it provided me a sense of introspection on how much I had done, what hindered my progress, and how I could plan for my first hour back at work on Monday. Granted, had I used that tool correctly, I might have made more progress the next week than I actually did. Unfortunately, however, half the time I used the "ups" to brag to HR about specific things I had done, because they had asked for that, I used the "downs" to complain about my workload and coworkers, and I wrote a somewhat sarcastic blurb in my plans for the future about how the next week I would be trying to get my head above water.
Emotions and attempts to look promotable get muddled with actual successes and hindrances when this self-evaluation is left to an individual. Primarily for this reason, making this self evaluation a personal responsibility of every team member is not a worthwhile approach.
In the sense of a meeting topic, however, this can go a variety of ways. The more pessimistic development team will focus on the flaws of the architecture, the system, the business side, customers, users, and everything that allows them to not enjoy their job. An excessively optimistic team will rejoice in the triumphs of the week without looking into what may have allowed it to go even better. My own experience has shown that the first two typically are the focus, where we can pat our own backs or vent our frustrations, but the real aim of this exercise is to plan for the future. Use the objective successes and objective failures of the past week/month/iteration/project to objectively plan for a realistic future. With some strict moderation of the meeting, you can keep it objective, under control, and effective.
It bears mentioning that for this author to suggest a meeting is extremely rare. I am of the mind that meetings are typically ineffective in promoting change, and expensive in the context of opportunity cost of resources. For example, having 30 salaried employees (say the average salary is 60K annually) for an hour in a meeting comes to one hour that costs $900, during which time no one is actually working, which costs even more. Only if meetings are short, consist of less than 10 people, and have one specific objective, would I consider holding meetings. In the context of planning for the future, using the past successes and failures, this meeting can help map out new strategies, or solidify existing ones, but it must remain short and objective.
Plan Utilities
Too often, a new feature is introduced, which requires a common, but different, structural change to your software solution. I myself have had to write the same exact structure of code, with only a few differences (properties, methods, namespaces). If you find yourself in this situation, you need to look into creating utilities.
Utilities are standalone products which act as "tedium reducers" for developers. They not only take a lot of grunt work out of developer responsibility, but also help to standardize the overall structure of code. They can be as simple as ID generators, as medially challenging SQL script writers, or as complex as entire code generators that create classes, scripts, stored procedures, and methods that are frequently used, but need to be part of their own class.
Many of the examples given beg the question, "Why is the architecture set up that way in the first place? Should you not focus more on fixing the overall problem than creating overly complex bandaids?" The answer to that is simple: you cannot always just scrap a given solution because you are frustrated with its structure. Many times, a solution is over ten years old, and there are not enough resources to build a brand new solution with new technologies while maintaining the existing one. A tremendously helpful weapon in your arsenal in such a case is someone who can (and does) write utilities to circumvent the tedium required to get around the elephant in the room, if for no other reason than to free up time to allow designers to address the bigger problem. During downtime, allowing a few developers a full work week to create a utility will provide long term savings in stress, business cost, and loyal employees.
Recognize Problem Code
In my own experience, defects stem from two to three of the same areas of code, and often for the same reason.
Developers code according to the standard of the company, and that may be something very specifically defined or loosely accepted. What often happens, however, is that there are issues which arise in only one area. At that point, even if you know that the issue is with the developer himself, you need to address how to reduce the problems in code. Usability of code, especially enterprise code, should not be written to separate the know-it-alls from the no-good, but to make sure that every developer at every level can contribute efficiently. Even a beginning developer -- or in some cases, a seasoned but stubborn and unreliable one -- should be able to make changes to code without significant risk. If they do not have the skill set at present to contribute and avoid the risk, the responsibility unfortunately but inevitably shifts to the more capable to simplify code and reduce potential for introducing errors.
Discuss Refactoring and Abstraction of Code
This area of conversation has two points of focus: how to clarify the code for the sake of analysis, and how to optimize code for the sake of performance and reduce redundancy. The two concepts are on somewhat opposite ends of the spectrum, but the end goal is the same: improve the speed of development.
Refactoring code, simply put, is changing the inner workings of code without changing the outer results. This can be done a number of ways, but the most common refactoring of code is to turn a very long function in code into several small methods. The purpose of it is to take a common procedure that is -- or at least, once was -- considered to be one entire process, and break it into smaller segments, often because a foreseen need for one component of that process in a separate process. Consider a function that accepts a string of text meant to represent a phone number, then turns out a US standardized phone number string (XXX-XXX-XXXX). Imagine that this function accepts the string of text, then strips out every non-numeric character. It then validates if you have the required number of digits (in this case, 10), then constructs the standard format by adding dashes at the 3rd, then 7th index of the numeric string. There are components of that function which can also be used to remove unimportant characters from dates and license plate numbers, to validate length of text, and to construct formatted strings based on a company standard (much of this is already built into the .NET framework, but for the sake of illustration, we will ignore that for now). You could refactor this function to call functions that handle just those components in succession, and still get the same result. The plus side is that you would have existing functions to call on later when you need to do something similar, such as format a date ("1/1/2016" vs. "2016-01-01").
What you notice as you refactor, however, is that your smaller functions are harder to understand what purpose they serve when it comes to output. This is what people are talking about (half the time) when discussing abstraction. The "act" of abstraction is taking functionality for a specific purpose, and making it more generalized. Analyzing and adjusting abstracted code is an area where a bit of human explanation is necessary to help incoming developers understand the workflow of coding solutions. For the most part, however, once you have a solid working abstract section of code, it's best to make this a "black box" library of your solution, where a developer simply calls the method and doesn't care how any of it works, so long as it spits out the results they want.
Where abstraction becomes a conversation/meeting of its own is when you start to disagree on how to structure your abstraction, and how you can change the item based on common concepts. This is not unlike the circle-ellipse problem. At this point, you have to look around the room and truly evaluate if you have enough people who are willing to dig this deep into the rabbit hole and come up with an agreeable solution. After all, downtime is usually very short lived, and you need to come up with a game plan for the next wave of work heading your way.
Conclusion
Sleep is a great parallel of the importance of downtime. During the day, humans are observably active. We see when someone is moving, we see the results of work, and we can verify effectiveness of any activity. When we sleep, no one can verify what repairs, improvements, and adjustments the body is making, but studies have shown that the brain is equally active during sleep, helping us to create memories, make repairs to the body, and influence the system to grow through creation of hormones. While external areas of the body show little activity, there is an internal frenzy of work happening. Likewise, downtime development can and should be used to focus on evaluating operations, reducing tedium, strengthening processes, and increasing efficiency. While stakeholders may not readily see the same high intensity in the IT department as they do during the development cycle's "high tide", the long term effects of using downtime for internal improvements can distinguish the good IT department from the bad. There is comfort in letting the brains behind your product focus just on the brains behind your product.