I hate that phrase, “Working hard, or hardly working?” It’s a mean-spirited jibe at someone’s effectiveness and work ethic. However, it says something about practice. If you are only going through the motions, you aren’t really practicing.
When discussing practice, it makes sense to identify two types. Practice, as in a practicing attorney, is the act of doing a thing. Practice, as in deliberate practice, is about isolating disciplines to find ways of improving. This second type is what I’m talking about today. It’s the soccer player dribbling around cones, the musician doing etudes, or the artist drawing a page of ears.
I’m going to define deliberate practice as “performing a discipline to gain feedback on the quality in order to improve proficiency. The key is ‘feedback’. Without the feedback cycle, we don’t improve. It is what makes the distinction in the phrase, “Ten years of experience, or one year ten times over.”
To practice, we deconstruct our performance into it’s constituant parts and strengthen our skills. The isolation is important, because it allows us to focus on one area for improvement at a time. Why isn’t doing as good as practice? A musician won’t focus on breath control and tonal quality while making a tricky 16th note run, so they perform one-minute drills, playing each note on a scale for one minute while maintaining centered tone. Sure, they may hit all the notes at tempo, but what about the quality of their attack, tone, volume, and speed of their transitions?
What does that have to do with Development? (Disclaimer, I say typical in the following because I still brush up against people from organizations who have these experiences. Your millage may vary) The typical factors effecting software development encourage “all performance, no practice.” The drive is to constantly move towards completion of the product. This is good, as we find business value and justify our paycheck. This is bad, because we don’t invest towards our future capabilities. I’m not talking about the perfect, flexible code that will slice, dice, and make julian fries. I’m talking about our ability to do a better job next week, month, or even year.
The typical industry workplace distracts us from improving in a couple of ways. The pressure on the project usually means the database expert does all the database code, preventing a sharing of knowledge and encouraging focus on existing strengths. Reviews, when done, are months removed from development and focus on finding defects. They are not intended to provide the more subtle feedbacks that will make fundamental changes in the way a developer addresses their work. Developers aren’t given time to explore and attempt to use new techniques and determine their impact on the fitness of the code base. All this leads to an environment that encourages stagnation and the status quo amongst the development staff.
Typical design reviews are done well in advance of development before any new lessons learned from the implementation of other parts of the system can be incorporated. Typical code reviews are delayed until the code is stabilized to reduce re-work. This means reviews happen well after the initial design decisions are made, so they can’t make meaningful comments on the larger patterns, but only look for defects or show stoppers. If we delay detailed design until we are actually working on a task, we see the code take shape while the design decisions are fresh. In addition, if the designer is actually the developer implementing their code, they learn what did and didn’t work well. Another way to get timely feedback is to target your development tasks at one or two days of work. This makes code review quick and doable as part of the normal work flow, the code can be reviewed before the developer being reviewed starts on new work. This starts to bring them into the practice feedback loop of do, evaluate, and do again. The tightest method of feedback is constant feedback. That comes from pair programming. Even if you don’t pair as part of daily routine, you should consider it as a means of knowledge transfer and training for ALL developers.
Practice is about strengthening your weaknesses. A quote from David Mead’s 10 Minute Acoustic Guitar Workout describes a player who had revisited several songs after a few years. He realized he still had the same problems in the same areas of those songs because he had not addressed those fundamental weaknesses, but practiced and played what he wanted. More correctly, what he could already do. If you encourage the developers to get done fast and perfect at all costs, then they will gravitate to what they already know. They will begin to have siloed code ownership. You’ll turn around and find out that the analytics specialist, the only one who knows that part of the code, is spending a week in the Keys, and you have a customer who wants a change NOW. This is an example of “bus-factor,” the degree to which losing a single team-member puts your project at risk. More insidious, they will drift apart in their understanding of the system because, “That doesn’t effect me.” If they don’t have a shared vision, they aren’t a real team. If the developers work on and share several sections of the project, you strengthen their weaknesses. Agile teams strive for ‘Generalist’ developers. This doesn’t preclude expertise, but that dev is now a reference and mentor sharing the knowledge. While one developer may be able to handle all the analytics now, what if you have to double her workload? If you have a team of UI developers, but aren’t focusing on the UI this release, do you let them go, or shift them to areas where they are needed?
Developers are usually not given flexibility to explore better ways of doing something. While uniformity make development easy, it can be a false prophet. “We can’t do that module differently because then we’ll have to change these two.” Experiment. Try it. Is it easier to maintain? great! Is it worse? Then you learned, and that’s valuable as well. Do you have to change solid, tested, working code because you have a new methodology? No. Wait to change the code until the requirements change. Often the first code laid down is fixed with rigidity, even if we find strong evidence for change. This can be a false economy. The local highway is expanding traffic lanes to accommodate more cars. Older homes are re-insulated and fitted with grounded electrical outlets. But developers seem to think the only way to change code is to burn it all down and start over.
This is about how an organization can try to enable the growth of its development staff. A lot of this points to lean processes and agile techniques. I’m not sure if the software craftsmanship movement, who prize practice so highly, developed the agile techniques because they sought feedback, or because they saw the effects of feedback, they began to understand practice.
Some time in the future, I’ll be addressing some practice techniques that individuals can use so they take some charge of their own growth. The organization can only do so much, you have to take it the next step.