The myth of “undesigned”

Some teams talk as if design is something you can add to software later, saying, “Oh, that interface we built hasn’t been designed yet.” That way of thinking is based on a fundamental error.

The problem

Many real-world teams treat certain kinds of design, including visual design, user interface design, and interaction design, as quantities that you can add later. Often this is done with the best of intentions.

For example, the team’s designer may be unavailable, so the rest of the team will get to work on a story, building an obviously rough interface. If, by the time they’re done, the designer still isn’t available, the product owner might accept the story as complete, making a mental note to come back later, perhaps much later.

When somebody external comments on the ugly interface, the developers might say, “Oh, that hasn’t been designed yet.” They’re wrong.

Software is nothing but design

People often talk about software with an implied analogy to industrial production. One group of people makes up some blueprints, and then an entirely different group of people makes physical objects. That second group is judged not by the utility of the objects, but by conformance to the design. This can sometimes be a useful analogy, but in an important way it’s entirely false.

In truth, the creation of software is 100% design. The computer does all the work of making things happen in the real world. The software is just the blueprint the computer uses to decide what to do. In the same way that a good manufacturer is one that follows the instructions well, a good computer is one that executes the software faithfully and reliably. All the humans participating in the creation of software are involved in a joint design activity.

“Not designed” is badly designed

So if software is pure design, then what’s going on with the ugly interface? The notion that it is somehow “not designed” is wrong. It’s just badly designed. Why does that matter? Because good design isn’t something you can spray on later like a new coat of paint.

Programmers already know that for the kinds of design they appreciate. Good developers try hard to avoid  spewing out reams of confusing, badly organized code that they hope to clean it up later. They know that’s wasteful, and likely to hide tricky problems. Tactically, they may choose to leave certain things messy for a short period. But experienced developers do that judiciously, painfully aware of how easily a controlled low-quality situation can turn into an uncontrolled one.

Teams should have the same attitude about every kind of design that matters for their project. Each story should be well designed from every perspective before it is declared complete. That sounds like it could be a lot of work, but it needn’t be. As with the software architecture, other sorts of design can be approached incrementally and iteratively.

The only hard part is making sure that you have all key contributors working together. The easy way to do that? Put them all in a room, and have them release something every week. They’ll figure it out.

Software engineering isn’t

There’s a long tradition (since 1968, according to Wikipedia) of looking at software development as an engineering discipline. But calling software development engineering is something like adhering to the letter of the law, rather than to the spirit

Software development is about acquiring knowledge

If you think of software development as strictly an engineering discipline, you might be inclined to believe that the job of a software engineer is to apply his or her previous knowledge and training toward solving a particular problem. And you’d be right, to a point, because knowledge and training are important aspects of software development.

But you’d also be missing the key factor, that software development is mostly about acquiring new knowledge. Software developers are always engaged in the following pursuits:

  • Discovering what to build
  • Discovering how to build it

This goes a long way toward explaining why so much software is custom software. If software development were entirely an engineering discipline, it is conceivable that we would be able to construct just about any software application by plugging together the proper parts, chosen from a catalog of well-known, existing components. The fact that we aren’t even close to being able to do that is an indication that we still have a lot of discovery ahead.

Discovering what to build

How do we discover what to build? By working closely (and continually, if possible) with the customer. By getting feedback as often as possible from real users, and by constantly applying that feedback to the product under development.

Discovering how to build it

From the developer’s perspective, this is a career-long pursuit, as new techniques for building software are always appearing. As software developers, we can provide the greatest benefit to our clients by being aware of new developments in the field, but tempering that with the client’s needs to meet specific schedules and cost targets.

For any particular product, we can practice Test Driven Development (TDD) and encourage emergent design, so that we avoid imposing our own pre-conceived (engineering) notions on the product, and instead develop just what the client needs (and no more).

Avoiding the knowledge transfer bottleneck

In software development there are many ways to transfer the knowledge about how to build a product to the people who do the actual building. Production can be severely hampered, however, if that knowledge is being produced more rapidly than it can be consumed. This is the knowledge transfer bottleneck.

I recently hosted a workshop that let participants experience three different ways of transferring knowlege in a production environment. The product, in this case, was a paper airplane of unusual design. The idea was to try different ways of transferring the knowledge about how to build the airplane from the “chief designer” (me) to the production workers, and to compare the relative productivity of the different methods, which were:

  • Documentation – The workers were given written instructions (22 steps worth) for building the airplane.
  • Reverse Engineering – The workers were given a completed airplane which they could study in order to reproduce the steps required to build it.
  • Mentoring – The “chief designer” built an airplane step by step and the workers replicated each step as it was performed.

The experiment was conducted in two phases. In the first phase, all 8 participants used the Documentation method. In the second phase, one team of 4 tried Reverse Engineering, while the other team of 4 tried Mentoring.

The results were interesting. Using the Documentation method, only one person out of a total of 8 came close to being able to build the airplane at all in the 5-minute period allotted.

Using the Reverse Engineering method, 1 person out of a total of 4 produced a completed airplane in 5 minutes.

Using the Mentoring method, each of 4 team members produced a completed airplane, and in less than the 5 minutes available.

The knowledge transfer bottleneck in software

In a software development effort, knowledge transfer takes place all the time, and it’s easy to imagine a software developer in the “chief designer” role described in the exercise above.

Let’s say I’m a developer who has discovered, and written the code to implement, a technique for binding some data to the controls in a user interface, and that this technique forms a pattern that my fellow developers want to know about. If you were one of my fellow developers, would you rather I (a) gave you a document I had written about the technique, (b) told you where the code was and suggested you figure it out for yourself, or (c) paired with you to implement the pattern for a new set of data?

Now, certainly, pairing with you takes more of my time, and might seem less efficient from my viewpoint. After all, I could be off designing the next pattern, and the one after that. But the  productivity of the team as a whole, rather than my personal productivity, is what’s important. And mentoring helps increase the team’s productivity by avoiding knowledge transfer bottlenecks.

Slow down to boost profits

A team in which everyone works at top capacity has got to be the most productive, right? This article explains why it ain’t necessarily so.

(Note: I didn’t invent the exercise described here. I first saw something like it presented at the Agile2006 conference by Ashley Johnson and Rich Phillips of Valtech Technologies, Inc.)

The assembly line analogy

I recently conducted an exercise with the folks at North Bay Agile in which two teams formed assembly lines for folding paper airplanes. Each assembly line consisted of a number of distinct operations, as follows:

  • Operation 1 – Get raw material (a sheet of paper) from stock.
  • Operation 2 – Fold inward lengthwise, then unfold.
  • Operation 3 – Fold top corners inward.
  • Operation 4 - Fold sides inward, fold in half, fold wings down.

In the first shift, every member of each team worked at top capacity. The result: Each team produced about a dozen airplanes in 5 minutes.

But then I had each team fill out a “profit and loss” statement. They got credit for “selling” all planes produced, but they were also debited for the labor and material costs of uncompleted airplanes (which stacked up in front of Operation 4, the bottleneck). The financial news: Both teams incurred a loss.

In the second shift, the teams were instructed to slow down to match the rate of the slowest operation. This was accomplished by creating a “buffer zone” before each operation and following a rule which said, “you can’t pass your work on to the next operation until that operation’s buffer zone is empty.” The result: Each team still produced around a dozen airplanes in 5 minutes.

When the profit and loss statements were filled out a second time, each team showed a profit. This was directly due to the fact that no work-in-process inventory built up, thus reducing the amount spent on materials and labor.

The most obvious difference in the overall activity of the assembly lines from shift to shift was that, in the second shift, the upstream operations were sometimes idle. By slowing the upstream operations to match the rate of the slowest operation, both assembly lines increased their productivity.

Increasing productivity stepwise

After the first shift in the exercise, the inclination of several participants was to try to find ways to improve the performance of the slowest operation. As the second shift demonstrates, however, a simpler first step is to just slow down all of the upstream operations to match the rate of the slowest operation.

The business novel The Goal outlines a process for increasing the productivity of a manufacturing system:

  • Step 1 – Identify the system’s bottlenecks.
  • Step 2 – Decide how to exploit the bottlenecks (e.g. don’t let a bottleneck be idle).
  • Step 3 – Subordinate everything else to the above decision (e.g. throttle back the upstream operations).
  • Step 4 – Elevate the system’s bottlenecks (e.g. speed up a slow operation).
  • Step 5 – If, in a previous step, a bottleneck has been broken (i.e. a bottleneck is no longer a bottleneck) go back to Step 1.

 As you can see, the recommendation is to slow down all non-bottleneck operations before trying to speed the bottlenecks up.

How does the assembly line exercise relate to software development?

Although software development is not the same as manufacturing, there are situations in development that exhibit the characteristics of an assembly line. Suppose, for example, that you are a developer building components for use by other developers. If you (the upstream operation) produce components at a rate faster than the other developers (the downstream operations) can understand and use them, you can create a bottleneck, causing excess “inventory” to build up.

Software development is about creating and sharing knowledge

Here are some simple things to remember when considering whether it is more profitable to work at top capacity or to be idle part of the time:

  • Knowledge is the inventory of software development
  • People consume knowledge at their own rate
  • Creating knowledge faster than it can be consumed causes excess inventory
  • Excess inventory reduces profits

In other words, working at your own top capacity may not be the positive thing you think it is. If you’re producing software components at a rate greater than the rate at which they can be put to use, you could be hurting the bottom line.

Fad-proofing your Agile adoption

As Agile methods become more popular, they risk turning into a pointless fad. Here are my tips for avoiding that trap on your own projects.

Agile is the new black

A friend of mine is a founder at a startup that’s very Agile: weekly iterations, releasing 2-10 times a month, heavy test coverage, and lots of pair programming. He met for coffee with a friend of a friend, an executive in charge of building his company’s first significant piece of software. Part of the conversation went like this:

My friend: So, how are you developing your software?

Executive: We’re doing Agile!

My friend: That’s great! We started out two years ago with a typical Extreme Programming set of practices, but since then we’ve made a number of significant changes, including [list of new and modified practices]. And we’re still continuously improving. How about you?

Executive: We’re doing Agile!

My friend: [Sighs, shakes his head sadly.] Nice weather we’re having, isn’t it?

In my experience, this is becoming more and more common: somebody hears that Agile is what all the cool kids are doing, so they take a very shallow understanding of what that means and run with it. This rarely works out well, and always puts me in mind of somebody who goes to a buffet restaurant and makes a meal out of the desserts. It’s theoretically appealing, but the long-term costs are fearsome.

Fad-proofing your Agile adoption

Agile methods have become popular because there’s real value to them. However, just jumping on the bandwagon won’t do you any good. Take the time to think through what you’re trying to achieve. Do an Agile adoption poorly and people may become cynical enough that you won’t have another chance. Here are 10 things you can do to help:

  1. Focus on what works – Your team isn’t there to create process or make software. You’re there to deliver sustainable long-term value via software. Use that as your primary ruler to measure success.
  2. Don’t expect miraclesThere are no silver bullets! Agile methods don’t fix your problems for you; they mainly make the problems obvious quickly, so you can solve them yourselves.
  3. Give yourself room – Thinking that “doing Agile” must be quick and easy, many teams don’t allow enough time to learn how to make the practices work well for them. Allow for an initial productivity hit, one that will get paid back richly down the road.
  4. Don’t get suckered – Now that “Agile” is a big buzzword, there’s an equally big incentive for consultants and authors to sell you Agile lite, the software process equivalent of cotton candy. Don’t fall for it!
  5. Don’t just “do Agile” – I’ll tell you a secret: there is no “Agile” that you can do. There is a collection of Agile methods; you can do any one of them. There are a whole host of practices to adopt. But unless you know enough to tell them apart, you don’t know enough to do any of them well.
  6. Get help from people who have done it – As a coach, I’m probably a little biased, but I think everybody who tries an Agile approach should involve somebody who’s done it before. Whether that’s a key player, a manager, or a coach doesn’t matter much. But it’s hard to learn Agile methods from books, let alone a couple of articles on the web.
  7. Track and pay down your debt – Part of an Agile adoption is raised standards. That leaves most people with a lot of cleanup to do. Make a list of all your code debt and testing debt, and have a plan for paying it off.
  8. Push power down – Agile methods do best in a context where teams are given broad latitude to solve problems on their own. Focus on supporting rather than directing your Agile teams.
  9. Improve continuously – An Agile method isn’t something like a turbocharger that you bolt on once and then use forever. If you aren’t having regular retrospectives and continually improving your process, you’re not Agile.
  10. Use your ignorance for good – One of the biggest mistakes people make is thinking that even though they’ve never used an Agile approach, they know enough to make big changes to it from day 1. Instead, accept that you’re trying something truly new to you, and act like it.

Feedback wanted

Have any war stories about the dangers of being fashionably Agile? How about tips on doing it right? I’d love your comments, and other readers would, too.

P.S. Hat tip to my old pal Christopher DeJong for the phrase “Agile is the new black”.

The 3 kinds of code

You can look at any chunk of code as belonging to one of three categories. Confusion between them plus a misunderstanding about the relative cost lead many people into trouble. With a little communication and some discipline, you can save yourself a lot of pain.

The 3 kinds

A few weeks back, I had to help smooth over a conflict between two co-workers. One was a seasoned developer. The other was a businessperson who just wanted some things added to their company’s web site. The conflict arose because they had very different ideas of the costs of software.

For their purposes, there were three plausible paths to take, matching the three kinds of code:

  • Temporary – Code written with a plan to throw away in a day, a week, or maybe a month. If it breaks, that’s ok — we were going to get rid of it anyhow.
  • Sustainable – Code that’s built to last. Well factored, well understood by the team, with strong automated tests, and generally meeting the team’s standards for something they’d happily maintain forever.
  • Half-assed – Everything in the middle. Code written by amateurs. Quick fixes that become permanent. Rush jobs. Things written when people say “we’ll clean it up later” and don’t.

When the businessperson expressed their desires, they wanted something cheap and quick. However, they didn’t want it to be fragile or throwaway; it had to be reliable and last indefinitely. They proposed bolting on an off-the-shelf solution that fell in the “half-assed” category. When the developer reacted poorly, they couldn’t understand why.

Follow the money

The misunderstanding comes because they had different perceptions of the costs:

Temporary low low
Sustainable high medium
Half-assed medium high

Given their perceptions, it’s natural that the businessperson would prefer the half-assed option. It’s more valuable to them than the temporary option. But doing things sustainably doesn’t get them any apparent increase in value, and they think it costs them more. Just as naturally, the developer resists what they see as the high-cost option.

In truth, they’re both right. They’re just looking at different sorts of costs. We can rewrite the column headers this way:

Temporary low low
Sustainable high medium
Half-assed medium high

The experienced developer is more aware of the long-term costs not only because they have more experience, but because long-term costs are generally thought of as their problem. As the maintenance costs of half-assed code add up, they won’t be attributed to last year’s excess schedule pressure from business stakeholders. Instead, the developers will be perceived as increasingly unproductive or unreliable.

Of course, that’s not just bad for the developers. It’s bad for the company as a whole. If a company’s costs for software continuously increase, that eventually becomes a powerful advantage for competitors who are more thoughtful and disciplined about their approach to software development.

Don’t fall in the trap

This is why many parts of the Agile world either explicitly or implicitly rule out the option of writing half-assed code.

Extreme Programming, for example, started out with a number of sustainability-focused practices, including pair programming, test-driven development, and merciless refactoring. As the book Planning Extreme Programming says, “With most of our planning, we assume that quality [is] fixed.” This continues up to the present day with efforts like Bob Martin’s Manifesto for Software Craftsmanship.

No matter what process you use, you can avoid the trap of half-assed code:

  1. Make sure everybody agrees that they are in it for the long haul.
  2. Educate stakeholders on how expensive supposedly cheap solutions are in the long term.
  3. Whenever people agree on a temporary solution, make sure that it is really temporary. In particular:
    • Agree in advance on the end date and expected issues. Write that down.
    • Budget for the costs of removing the temporary solution.
    • If a permanent solution is to follow the temporary solution, budget for that, too.
    • When the end date approaches, people will try to fudge it. Politely refuse, reminding everyone of the earlier agreement.

In addition, be constantly vigilant about half-assed code returning in disguise. For example, a lot of people get sold on outsourcing or offshoring because it looks cheap and easy. Sometimes it might be, but most of the projects like that I’ve seen are really half-assed code that got sold as sustainable. Just as dangerous is the cowboy coder who rides in to save the day, but leaves a lot of half-assed code behind for other people to deal with.

Mindful engineering

I’ve been pondering lately what was special about the teams I’ve been on that have felt the most effective to me. It wasn’t just a certain set of practices, though those were helpful. The essence, I think, was a certain openness to ourselves and to each other, a willingness to really look at what we’re doing and how what we’re doing affects the project, ourselves, and each other.

Retrospectives are a specific practice that provides regular opportunities for this kind of openness. But even more, when I’ve really felt productive there’s been a pervading attitude on the team that it’s always okay to take a moment to explore some interaction or event at a deeper, more personal level.

One day, on a team of four, we were programming in two pairs. At some point my partner and I noticed that the other pair had reduced to a solo. We asked, “Where’s your partner?” and he replied, “I think he got upset with me.” My partner replied, “Well, I hope we can talk about that later.” And the really amazing thing is: We did. The partner returned, and described what he had gotten frustrated about, and we were all able to talk constructively about how to deal with that kind of frustration.

Another day, on another team, also while pairing, I noticed my partner withdraw and get quiet. I wasn’t quite sure why, though I was aware that we had been debating some technical point. She started to go on with the task, but I stopped to ask what was up, and she said, “I’m just not getting much ‘Yes, and…’ from you right now.” We had both learned the “Yes, and…” principle from improv classes—which I highly recommend—and it was an easy way to remind ourselves to respect and build upon each others’ ideas rather than only pursuing our own. This quick check-in in the middle of a task short-cut what could have been a long period of frustration, leading instead to a productive, collaborative session.

As I said, this isn’t about specific practices as much as it is about a thorough willingness to talk to each other openly and to respect each others’ thoughts and feelings. Obviously, I think that Agile practices, especially retrospectives and pair programming (when done well), are a good way to foster this kind of openness. In fact, what first drew me into the Extreme Programming community was the openness to learning that it demonstrated.

In my short career up to that point, I felt that I wasn’t really learning much—I was already a pretty good programmer, but the really tricky problems on my projects were less about programming and more about communicating with each other and with the project’s stakeholders and about finding ways to keep everyone sane in the face of growing complexity and business uncertainty. These were the real challenges, but no one was really addressing them—until I found the XP community, who were meeting every month to talk about exactly these issues, and about what they were trying and what they were learning about them.

Now, of course, this kind of concern for how we work together is not the exclusive domain of Agile communities, though some of us often talk that way. The CMM community is likewise dedicated to trying new things and talking candidly about how they’re working, albeit with a more formal approach. The Space Shuttle software project case study described in the CMM book is actually quite an inspiring story of worker empowerment and process experimentation and improvement over time.

Why do many in the Agile community criticize the CMM, lumping it together with the straw man process known as “Waterfall”? I think that Waterfall is an example of formality in a process without authentic openness and introspection. When a manager looks at an undisciplined project and sees it spinning out of control, the most common reaction is to impose some control with some mandated formality. The CMM may be used as a framework for that formality, even though the authors of the CMM themselves strongly warn against using it to impose formality without honest assessment and openness to continuous improvement attached. (They even have nice things to say about XP.)

I’ve been exploring the practice of mindfulness lately, and I think it nicely captures the kind of openness and introspection I’m talking about here. Mindfulness can be practiced through activities such as meditation, improvisation, journaling, and reflective listening, and has documented benefits for compassion, empathy, concentration, and even happiness itself.

I can easily see the appropriate level of formality varying based on the nature of the project, but this quality of mindfulness seems essential to any endeavor. Agile methods tend to be moderate to low on the formality scale, and—when they work—high on the mindfulness scale.

How are you mindful of your work? How are you not?

Marshmallows, mortgages, and metacognition

One of the reasons traditional processes fail is that they are fitted to how people think they think, not how they actually do. Below I link to two interesting articles about how people think, and talk about the software process lesson I draw from them.

Waiting for marshmallows

Ninja programmer Brian Slesinsky recently pointed out to me this great New Yorker article: “Don’t: the secret of self-control.” 40 years ago, a psychologist performed a simple experiment on small children: He told them they could have one marshmallow now, or two if they waited a bit. Unsurprisingly, some children managed to do it; some didn’t.

The interesting part is why, and what happened later. Following up over the decades, it turns out this sort of self-control is powerfully predictive of success in life. One researcher found that the ability to delay gratification was better than IQ scores for predicting grades.

But how did this work? Do some kids just have more willpower than others? Was it just that some didn’t have all the facts about what they’d get when? No, it turns out. Instead, the children best at waiting put the marshmallow out of their minds. They covered their eyes, or sang Sesame Street songs. Focus on the marshmallow and you were guaranteed to lose. In other words, the successful children changed their situations to support the right sort of thinking.

Waiting for foreclosure

In this weekend’s New York Times there was an article “My Personal Credit Crisis”. The writer, Edmund L. Andrews, opens:

If there was anybody who should have avoided the mortgage catastrophe, it was I. As an economics reporter for The New York Times, I have been the paper’s chief eyes and ears on the Federal Reserve for the past six years. [...] I wrote several early-warning articles in 2004 about the spike in go-go mortgages. Before that, I had a hand in covering the Asian financial crisis of 1997, the Russia meltdown in 1998 and the dot-com collapse in 2000. I know a lot about the curveballs that the economy can throw at us. But in 2004, I joined millions of otherwise-sane Americans in what we now know was a catastrophic binge on overpriced real estate and reckless mortgages.

Again, knowing the facts weren’t enough. There were few people on the planet with more information about the topic, and he had unfettered access to people who knew the rest. But when he put himself in a situation where circumstances combined to reinforce his desires, mere knowledge wasn’t enough to save him.

So what’s this have to do with Agile development? I see two related lessons:

Product dreams

Think, for a moment, about the classic waterfall dream:

  1. you work hard to make a big plan,
  2. you follow the plan for a long time,
  3. you produce what you planned,
  4. and then you have a big success.

This can go off the rails in a number of ways, but key to many of the failure modes is that it mostly avoids contact with the external world up until the end. People spend most of their time in a context where their focus is on conforming to other people’s notions, rather than the real environment.

On a truly Agile project, you try to avert this through particular practices, like frequent releases, weekly iterations, and energetic engagement with users and stakeholders. Rather than pretending that you can imagine your way to a good product, you put yourself in a situation where the environment pushes you toward a great product.

Technical dreams

This has parallels on the technical side.

All good programmers like to build things. In the wrong context, this can lead to developer gold-plating and infinite infrastructure. I once saw (but, thank goodness, didn’t work on) a system that spent $120 million on years of planning, development, and initial rollout. Many years into the project, it only had 4 working screens, which wasn’t enough to be useful to anybody. But it had plenty of infrastructure.

More insidiously, technical choices tend to be self-reinforcing. Suppose in the first week of a project a team starts out with an SQL database, just because it’s convenient. If you point out to the programmers that they’re making a big technical choice on the basis of minimal data, they will say: of course we can change the design later. But there’s a reason that those programmers work for a paycheck while Oracle’s Larry Ellison has $20 billion in the bank and collects exotic jets. Only Larry understands that very shortly they will have a hard time even conceiving of making that change.

To avoid these perils, it’s important to follow practices like simple design, pair programming, automated testing, merciless refactoring, and YAGNI. But just as important is to think just like great product managers do: treat the project as a series of small bets. Instead of grand architecture visions, it’s more effective to continuously run small experiments that help you decide between different design options.

If you structure your environment to force continuous learning and small, feedback-driven steps, your thinking will come to reflect that. And you’ll be better off for it.

A sample weekly schedule

One of the things I get asked a lot is which meetings a team should have when. The right answer is that it varies for every team, and it changes over time. Still, it can be handy for new teams to have a starting point. In that spirit, here’s a schedule that I’ve assembled based on a few different smooth-running teams:

The schedule

When What Who
Monday, 9-10a Iteration planning & kickoff All team members
Tuesday-Friday, 9:30-9:40a Stand-up meeting All team members
Tuesday, 2-4p Product stakeholder meeting Product managers, external stakeholders
Wednesday, 10a-12p Product planning Product managers
Wednesday 4-5:30p Estimation All team members
Friday, 4-4:30p Product demo All team members, external stakeholders
Friday 4:30p-5:30p Process retrospective All team members

Isn’t that a lot?

For everybody except the product managers, that’s under 5 hours of formal meetings per week. Once a team is running smoothly, I see many people doing it faster than that.

Still, it’s much better to allocate extra time for these meetings, especially at the beginning. Making an agile transition is hard enough without the stress of blowing out time boxes. Instead of squeezing the schedule down, develop the habit of looking to end meetings early. Only once you consistently end early should you shorten the schedule.

Even as scheduled, this doesn’t end up feeling like a lot. The daily stand-up should be fast-paced and energizing. The meetings that developers must attend are all at the beginning or end of the day, yielding large blocks of uninterrupted coding time. And the Monday morning and Friday afternoon meetings come at times when people are normally spinning up and winding down anyhow.

Notes and caveats

For this schedule to make sense, the team must:

  • be doing weekly iterations
  • have an on-site product manager (aka XP Customer, aka Scrum Product Owner)
  • sit all in one room
  • use lightweight artifacts (e.g., index cards, not requirements phone books)

You can divide the meetings up into three groups:

  • The iteration planning and daily stand-ups cover what we are doing now.
  • The product stakeholder, product planning, and estimation meetings figure out what we may be doing soon.
  • The product demo and process retrospective look at what we just did.

The notion is that although the team is mainly focused on what’s going on now, product managers (and sometimes designers) need to work a bit ahead, so that the team can move smoothly into the next iteration.

It’s also important to note that plenty of conversation happens outside of these times. That’s why we all sit together. Rather than trying to make a schedule that formalizes every bit of useful discussion, it’s better to schedule only the minimum number of meetings to get everybody in sync.

Feedback wanted

Does this leave you with questions or suggestions? Let me know, and I’ll cover them in a future post!

Start at the end

Any software development effort involves the conveying of information, but it’s easy for the important information to be hidden by related (but less important) stuff. Starting at the end is a good way to focus on the information that matters most.

Drawing Maps

In the days before Google Maps, we used to ask other people for directions to places we wanted to go, and often someone would volunteer to draw a map on paper. After taking part in many of these information exchanges, I observed that most people (including myself), when drawing a map, start at the beginning. That is, they start the drawing at the traveler’s point of origin and proceed from there to the destination.

The result was almost always adequate for the intended purpose of getting the traveler from point A to point B, but I noticed that the destination often ended up being crammed into a corner of the page, almost as if it were an afterthought rather than the most important piece of information on the map.

Now it certainly makes sense to draw a map in this fashion. I imagine that the main reason for doing it this way is that when drawing a map we imagine ourselves actually taking the trip we’re describing. We start at the beginning of our imaginary trip and eventually find our way to the destination.  And unless we begin with an inordinately large piece of paper, or are particularly good at allocating space ahead of time, we end up with a map that contains extra information we really don’t need, while details of the destination are omitted because we run out of room.

So I started drawing maps from the end. The first place I put on a map is the destination. From there I work backwards, drawing the streets leading to the destination. Then, if I have room, I draw the highways leading back to the city of origin. The result is a map that emphasizes the important details.

Communicating Technical Information

I’ve noticed a similarity between the way people draw maps and the way they convey technical information. That is, they often tend to start at the beginning and proceed in chronological order to the end.

Just as in map drawing, this approach makes a certain amount of sense. It’s natural for people to convey information in the order in which they discovered or developed it. The communication of the information is kind of a chronological account of the original experience of creation.

The problem is, it’s the end (the destination) that I’m most interested in. I tend to think of the result as the important part, with everything leading up to it being more like “supporting information” which I may or may not want (or even need) to know.

In other words, I tend to get lost in the details of the journey, when what I’m really interested in is where I’m going to end up.

Writing Software

I used to write code from top to bottom. That is, when I wrote a method I would start at the top of the method, and write lines of code in the order in which they would be executed. It made sense, in a way, because I was taught to read and write English from top to bottom. It seemed the natural way to go about it. Unfortunately this approach tended to introduce unnecessary code into the method that had to be stripped out later.

Now when I write software, I like to start at the end. When I write a unit test, for example, I start by writing the assert statement, even if it asserts against objects that don’t yet exist. I start with the assertion, then I see what the assertion requires and I write a line of code above it to satisfy those requirements. If satisfying those requirements introduces new requirements, I write a line of code above that, and so on.

The result is a unit test that carries no extra baggage, no superfluous information, with an emphasis on the most important part, the assertion.

The assertion in a unit test is analogous to the destination on a map. Both are the most important pieces of information. Both make excellent starting points.

Clicky Web Analytics