Adaption SoftwareThere is a revolution going on.
 . Home . Contact .   
You are Not Your Code

You are not your code. If someone finds a bug in your code, that does not (necessarily) represent a flaw in your skills. And flaws in your skills, should they exist, do not represent flaws in you, the individual. These are truisms, of course, but bear with me for a bit. Far from being your code, you do not, in most cases, even possess it. You likely share the code with other programmers who help maintain and extend it.

If you do not share it today, you shall tomorrow: if you switch jobs, retire, or die, you may be gone from your code, but your code will remain. Unless it has exhausted its value, others will inherit it. Someone likely paid you and your team to write it, and therefore owns it in every sense. Even if you do indeed own some code legally, much of it likely has customers and users who also have a stake in it. So, quite importantly, you share your code with those other stakeholders. So no, indeed, none of us "is" or even "are" our code. It's such an obvious thing, put that way.

Bad Scenario: Individual Identity Attachment

The problem is that many of us can agree that all of this is obviously true, but then behave otherwise entirely. Take the example of an average programmer's reaction to "bad news." Someone finds an (alleged!) flaw in "our" code. Perhaps we cringe, outwardly or inwardly. Or perhaps when we review past code of ours, self-judgment comes up: we cringe at the ignorance it seems to exhibit. How could we have been so simple-minded? Or perhaps someone asks to review our code or pair with us on a change to it, and we resist, a little or a lot, outwardly or inwardly.

Even in the absence of bad news, we can get quite worked up about completing some individual programming task in "our code" on time, without defects. Even the little flaws we discover on our own as we work (whether or not we test-drive) can seem to silently accuse us of incompetence. And the little blockages - those periods when we cannot quite solve the problem, due to some lack of framework knowledge, or algorithmic expertise, or sleep, or whatever. We can easily "wrap ourselves around the axle" about these little challenges. We can postpone for too long the simple act of asking for help, even if it might save us minutes or hours.

So we seem surrounded with these little temptations to feel bad about "our code." Now of course there are programmers (more all the time) who do not feel threatened by these stresses. Their self-conceptions as persons and as programmers remain intact, they don't feel especially bad, and they don't react negatively. But too many of us do feel and react badly, too much of the time. We feel, and perhaps behave, as if someone has poked an angry finger in our chest. To put it in terms of consciousness development, we have attached our identities to the code that we have individually created. This is what it means to "take things personally," or to "take things to heart," or to "get too attached" to something. In this case it means we confuse the things we produce with ourselves.

Bad for Us, Bad for Our Code

So why is this important? It's important because these kinds of reactions and behaviors are dangerous symptoms of team dysfunction. They are symptomatic of fractured software groups that are not truly teams at all, but merely loose aggregates of isolated, alienated individuals, failing to truly pull together.

Several problems can arise from such fractures:

  • Programmers are less likely to share code and knowledge, and less likely to listen to, work with, and learn from each other
  • Programmers are less likely to reach out for help when they need it, and more likely to spend long periods being quietly "stuck" and unproductive
  • "Silos" of knowledge are more likely to occur
  • Programmers are under more stress
  • Code is less likely to be reviewed and revised
  • The code is more likely to "rot"

The above problems can result from other causes as well, certainly. But they are all likely to be exacerbated when programmers identify too strongly with their individual creations.

Worse Scenario: Two Teams, Us and Them

So far I've been talking about attachment by an individual programmer to some individually created code, but collective identity attachment to a system by a team of programmers can actually be worse, if the customer is not felt to be on the same team. This two-team rift is the classic consciousness barrier in software development, the wall between "us" and "them." In a waterfall or chaotic software shop, this is the wall over which requirements and designs and finished code get tossed back and forth at too-infrequent intervals, with too much formality and too little human conversation.

Subconsciously, this wall exists in all of the programmers' minds and business stakeholders' minds. By limiting the extent to which we care about each other's work, it limits how well we work together. It limits truly creative, truly collaborative problem solving. Customers don't convey in sufficient detail what the underlying business problem or business context is for a given requirement. Not knowing (and perhaps not caring enough) about this business context, programmers can't or don't think creatively enough about simple, elegant ways to provide it for that requirement. In this case:

  • The programming team is less likely to solicit, much less welcome, enough input and feedback from customers to solve the problem optimally.
  • Programmers are likelier to build the wrong features, build them badly, build them in the wrong order, or build them too expensively or too late. These are, of course, the cardinal software sins that still, by and large, define software projects these days.
  • Political rifts and power struggles can arise between the two teams.

"Us" Getting Requirements Changes from "Them"

Let's say the programmer team receives a big, mid-project requirement out of left field from the customer team. This requirement will mean big design changes, big changes do production code and test code, and lots of reprioritizing and planning. Let's further say that in this case, the programmer team is cohesive. They do actually feel that they share the source code - its design and health. But in this scenario customer representatives are not part of that team. They are definitely "them." So how does the programmer team want to react? Perhaps somewhat tribally. How many times have you heard programmers joking or whining about customers? If only they would make up their minds, those pesky customers. Do they think we can read their minds? Can't they see the value of architecture, design, and proper frameworks and tools? Do they have any idea how hard these changes are? How hard programming is in general? Do they know how ugly the code can get when it gets jerked back and forth like this?

Whether we ask these questions internally or out loud, these are the wrong questions to ask. They are fear-based, combative, perhaps competitive, and certainly exclusionary. They are win-lose, not win-win. They are looking for an enemy, a scapegoat. When these are the kinds of questions we ask ourselves in response to requirements changes, our work is, to some extent, doomed.

Getting to "Whole Team"

The main practice I'm describing is "Whole Team" as described by Kent Beck in both editions of Extreme Programming Explained. There must be a single team solving the business and technical problems together. There are some specific characteristics to this oneness. Notice I'm not really talking about the quality of team communication (at this point). I'm just talking about the way we feel about who our work product "belongs" to, how we feel about "sharing" it. It might seem like a subtlety, but it's important. You can't have good team communication without a good team. You need good team boundaries and team practices first. It's critical that software teams include the people with the technical responsibility, authority, and skill, along with the people with the business responsibility, authority, and skill. It's not nearly enough that they share the same email domain name or mailing list, or the same building. It's often not nearly enough that they share the same floor of the same building. They have to be closer than that, physically, procedurally, and emotionally.

There are several practices, most of them from Extreme Programming (XP), that actually require teams to communicate with each other extensively. But you know what? That's not enough to get to a Whole Team. We have to use the practices to create teams that ring through and through with the right membership, strongly shared common goals, high ambient trust and respect, good feedback loops, and easy and extensive communication.

Really good teams have to have a certain consciousness to them, a certain level of collective and individual awareness. They have to feel right. This is the subjective essence of the true source of awesome software systems. We don't have to shower together or eat every meal together, but we do have to spend an awful lot of time with each other, getting to know each other quite well, and we have to use some individual and collective discipline to pursue certain team-building practices. These are not all the practices I recommend for making awesome software, they are just the ones that relate to creating and maintaining an awesome team. But that's where I always start.

Team-Building Practices

Here is the guiding principle for healthy software teams. On a good team, a business problem feels like everybody's problem, and a technical problem feels like everybody's problem. Regardless of my individual problems, I can rely on the whole team to help me solve them.

Here is a partial list of the practices related mainly to bringing programmers and customers together:

  • Team formation rituals
  • Shared space
  • Iterative, incremental delivery
  • Working together a lot
  • Ubiquitous language (consistent use of problem-domain terms)
  • Daily status meetings
  • Weekly retrospectives
  • Tracking status together
  • Celebrating together

(Note that it is possible, though difficult, to get a strong sense of a Whole Team when teammembers are not physically together. I claim that the team must have already been together physically long enough to have created that wholeness before they attempt to work together remotely. At that point, I would insist on regular, scheduled remote meetings (via telephone, video conferencing, chat, and remote pairing with a shared desktop). I don't believe that such remote arrangements ever work as well as being in the same room together. But they can be made to work, if one stays vigilant about their health.) And here, on the other hand, are practices related to keeping the programmers themselves oriented collectively around the code:

  • Common codebase
  • Continuous integration
  • Pair programming (at least some of the time)

What a Whole Team Looks Like

Together, the practices should have the effect of increasing the closeness of all project stakeholders, strengthening a sense of collective identity that explicitly includes everyone's values and priorities. This shows up in where we take pride - in particular, in the extent to which we take pride together instead of separately.

On great teams, we learn to feel that the system, including its technical and business characteristics and artifacts, belongs to us all. This effects the subconscious motivations and behaviors of all team-members. Once, as a programmer, you become close to Jeff the Product Manager, sharing his business triumphs and tragedies, you feel for Jeff. You more easily share his work values and priorities. It is no longer abstract if the system is not in the shape Jeff needs it to be in before the big Spring tradeshow. You end up asking Jeff after that tradeshow "Hey, Jeff, how did the demos go? How did people react? Did you close any deals?" At a deep level, instead of saying to yourself, "I am the programmer who produces elegant, bug-free code," you learn to say to yourself "I am the programmer lucky enough to work on a great product team; together we crank out tons of business value per week, in the form of beautifully crafted code."

How are We Doing?

Let's return to our bug news example. If we have a strong sense of a Whole Team, then if one of us is informed that a bug or design flaw has been found in our shared codebase, we are less likely to feel a real threat at a personal level. The more we are identified with the whole team, the more easily we can take such bad news in stride. After all, we have the entire team to rely on. We can work with our teammates to fold that flaw into the rest of the new tasks, bug fixes and refactorings that make up the planning for the next iteration. When the right time arrives to deal with that flaw, the team calmly and purposefully decides how to craft a solution to it, and how to allocate resources to get that done.

By comparison, let's look again at the unhealthy individual reaction to bad news. As sketched above, a more-or-less typical, unhealthy reaction to a discovered flaw might be for an individual programmer (the one who "owns" the code) to immediately and informally reprioritize their work. Full of dread, or perhaps resentment, he or she drops whatever they had been doing (with or without the input of colleagues and superiors) and pounces on the flaw, spending whatever time is required to find and resolve it, working alone.

This unhealthy reaction disturbs the team's work prioritization (and perhaps therefore threatens deadlines). It isolates the knowledge about the flaw and its fix to one team-member, potentially leaving the team vulnerable to an identical or similar bug. It perhaps allows the code itself to deteriorate, rendering it messier in the interests of dire emergency. And it helps sustain a frenzied, hurried, stressed work environment, in which priorities are in a constant, churning froth. From an organizational standpoint, it's clearly an unhealthy reaction. Let's now look again at our massive out-of-left-field new business requirement. If the programmers and customer representatives are identified together with delivering the most business value possible, then they might transition pretty swiftly to a sense that this new requirement is simply a business necessity. After all, in such a team, a business problem feels like everybody's problem.

Conclusions

In the software world, without a Whole Team, we really don't have anything. We're dead on square one. We should treat the creation of a Whole Team as vital and primary. We should get out of the habit of talking abstractly about the nature of a Whole Team, and talk and think about it more concretely, in terms of the practices that produce it, and in terms of how we can measure its quality in the reactivity and equanimity of individuals and groups of programmers and customers.

-- Patrick Wilson-Welsh, Adaption Software     revised 8-23-06

[More of Adaption's Articles.]


ADAPTION NEWS