©2007 George Dinwiddie
As a software development consultant and coach, I help software developers become more effective at developing software. Helping a team become more effective takes more than technical expertise. Sometimes helping does involve teaching technical skills. Sometimes, it involves helping teams change the environment in which they work. Usually it’s a little of both: technical skills may be the avenue to change the environment; changing the environment leads to adopting new technical practices.
What appears obvious to me, when I make my assessment of the situation, is most likely completely foreign to those I’m helping. After all, if they knew what I knew, they wouldn’t have these problems. It should be as simple as telling them what to change and directing them as they do it, right? Why do they resist what’s good for them?
Change is difficult for people. There are many, many reasons why they may not go along with my suggestions. Libraries of books have been written about facilitating change, or dealing with it.
A couple of years ago, I was engaged to help a client extend a J2EE web site that had been in production for a number of years. It was the system that the development team had built as they first learned Java. It worked well-a real testament to the skill and care the developers had applied. It was, however, becoming rather difficult to extend. Small changes tended to make odd bugs pop up in other places. The short description is that the code was very procedural in nature, rather than object-oriented. There was duplication where blocks of code were copied and modified for new features. There was temporal coupling where dissimilar things were being done in the same place because they needed to be done in the same HTTP transaction. There were code objects that extracted values from data objects, operated on them, and put them back.
I could clearly see that refactoring this code into good object-oriented practice would reduce the complexity, reduce the unwanted coupling that caused unexpected bugs, and reduce the time it took to add new features. I wrote up a description of the types of changes I was proposing and made my pitch to the team. As I talked about making these changes (and making them incrementally, as we added newly requested features), I could tell that they weren’t really enthused by the idea. I poured on the heat of persuasion, describing the benefits in the short term of the immediate features we were developing. The less progress I made, the more enthusiastic I became, scribbling UML diagrams on the whiteboard and building castles in the air as I pointed out the advantages in the long term of making some significant changes we knew were coming down the pike.
I got nowhere but exhausted. I stopped, wondering how I could get these procedural programmers to understand the benefits of object-orientation. I was trying to figure out what to say next when a senior member of the team said, “I don’t think there’s anyone in this room who doesn’t believe you when you say this is a good thing to do. We just don’t know how to get from where we are to what you describe.”
Oh.
I guess I should have asked more questions.
How did I get over this “resistance” to my suggestions? I can think of three distinct ways, demonstration, discussion, and retrospection.
I would have preferred to accomplish both the demonstration and discussion by means of pair programming. I’ve had great success doing that in the past, even at places that didn’t ordinarily do pair programming. The knowledge transfer that can take place with two people sharing one computer, screen, keyboard and mouse is truly awesome. In this case, half the team was in another city, and corporate policies forbade installing any software that would make sharing bearable over that gap.
It is often easier to do something than it is to describe it. I set to work refactoring code to eliminate duplication and encapsulate functionality within objects. I worked in small increments, checking the changes into version control on a frequent basis. Modern IDEs, such as Eclipse, often provide a convenient window for reviewing changes as you synchronize with the repository. I use this to keep an eye on changes others are making to the system, and I encourage it’s use. The demonstration is focused around what I did, as I provided examples of what I intended, while working on a new feature and refactoring old code to support it.
The discussion is balanced between us, with questions and suppositions and assertions flowing freely in both directions, between peers. Sure, when I’m teaching something, then much of the discourse flows from me. I describe what I’m doing and why. But there’s just as much flowing back to me, describing the context, and why things are the way they are. As I learn more about this context I find myself fine-tuning my approach to to problem. On top of this, there are new ideas that we generate together.
The retrospection lay on their shoulders. I facilitated the discussion while remaining outside of it. They owned what they had learned, where they wanted to go, and what still puzzled them. Had I to do it over, I would have introduced retrospectives earlier and more often. I was amazed at the difference it made to have an explicit ceremony to look back at the choices and progress made. It only makes sense, but often we expect learning to take place without allotting time for it.
Whether my work involves technical practices or changing the environment, I’m most successful when I meet people where they are and help them see the path to a better way of working. I can’t change others, but I can make the path easier to follow. Showing the way involves more than describing the goal and the benefits of reaching it. It requires showing those first little steps of the journey, too.
I got an email today from one of the senior developers on that project. He told me of the progress they were making converting other parts of the system to follow the example I’d left. He’s very happy with the way things are going. You know what? So am I.