Software Decision Making Under Stress

I recently blogged about my discomfort with making software design decisions at “the last responsible moment” and suggested that deciding at the “most responsible moment” might be a better approach. To me, a slight semantic shift made a difference in how I felt. Deciding at “the most responsible moment” made me feel less stressed and more in control of the situation.

But is this because I am basically lazy, preferring to put off decisions until they absolutely, positively must be made (and then hating that gut wrenching feeling when I finally realize that I don’t have enough time to think things through)? Or is something else going on?

I admit that the decisions we make about software development on a day in/day out aren’t always made under extreme stress…yet I thought I’d see what researchers say about decision-making under stress. As a developer I benefit from some stress, but not too much. That’s why (reasonable) deadlines and commitments are important.
But first, a disclaimer. I have not exhaustively researched the literature on this topic. I suspect there are more relevant and recent publications than what I found. But the two papers I read got me thinking. And so, I want to share them.

Giora Keinan, in a 1987 Journal of Personal and Social Psychology article, reports on a study that examined whether “deficient decision making” under stress was largely due to not systematically considering all relevant alternatives. He exposed college student test subjects to “controllable stress”, “uncontrollable stress”, or no stress, and measured how it affected their ability to solve interactive decision problems. In a nutshell being stressed didn’t affect their overall performance. However, those who were exposed to stress of any kind tended to offer solutions before they considered all available alternatives. And they did not systematically examine the alternatives.

Admittedly, the test subjects were college students doing word analogy puzzles. And the uncontrolled stress was the threat of a small random electric shock….but still…the study demonstrated that once you think you have a reasonable answer, you jump to it more quickly under stress. (Having majored in psychology and personally performed experiments on college students, I can anecdotally confirm that while college students are good test subjects, one should take care to not over-generalize any results.)

So, is stress “good” or “bad”? Is systematically considering all viable alternatives before making a decision a better strategy (or not)? Surely, we in the software world know we never have enough time to make perfectly researched decisions. And big-upfront-decision-making, without confirmation is discouraged these days. Agile developers believe that making just-in-time design decisions result in better software.

But what are the upsides or downsides to jumping to conclusions too hastily? What happens if you feel too stressed when you have to make a decision? To gain some insight into that, I turned to a summary article, Judgment and decision making under stress: an overview for emergency managers , by Kathleen M. Kowalski-Trakofler, Charles Vaught, and Ted Sharf of the National Institute of Occupational Safety and Health. These authors raised many questions about the status quo of stress research and the need for more grounded studies. However, they also drew three interesting conclusions:

1. “Under extreme stress [think natural disasters, plane crashes, war and the like], successful teams tend to communicate among themselves. As the emergency intensifies, a flatter communication hierarchy develops with more (unsolicited) information coming from the field to the command centre.” Under stressful, emergency situations, communication becomes streamlined and localized. Also, people take personal initiative to inform leaders about the situation.

2. Stress is affected by perception; it is the perceived experience of stress that an individual reacts to. When you perceive a situation as stressful, you start reacting as if it were stressful. What is stressful to you is what’s important. And not everyone reacts well under stress. Training helps emergency responders to not freak out in an emergency, but those of us in the software world aren’t nearly so well-trained to respond to software crises. When is the last time you had software crises training?

3. “Contrary to popular opinion, judgment is not always compromised under stress. Although stress may narrow the focus of attention (the data are inconclusive), this is not necessarily a negative consequence in decision making. Some studies show that the individual adopts a simpler mode of information processing that may help in focusing on critical issues.” So, we can effectively make reasonable decisions if we find and focus on the critical issues. If we miss out on a critical issue, well….things may not work out so well.

Reading these papers confirmed some suspicions I had: Stress is something we perceive. It doesn’t matter whether others share your perception or not. If you feel stressed, you are stressed. And you are more likely to make decisions without considering every alternative. That can be appropriate if your decisions are localized, you have experience, and you have a means of backing out of a decision if it turns out to be a bad one. But under extreme stress things start to break down. And then, if you haven’t had “emergency” training, how you respond is somewhat unpredictable.

I hope that we can start some ongoing discussions within the software community about design decisions and decision-making in general. How do you, your team or your management react to, avoid, or thrive on stress? Do you think agile practices help or hinder decision-making? If so, why? If not, why not.

Posted in Agile, Psychology, Software Design | 2 Comments

Agile Architecture Myths #2 Architecture Decisions Should Be Made At the Last Responsible Moment

In Lean Software Development: An Agile Toolkit, Mary and Tom Poppendieck describe “the last responsible moment” for making decisions:

Concurrent development makes it possible to delay commitment until the last responsible moment, that is, the moment at which failing to make a decision eliminates an important alternative.

And Jeff Atwood, in a thought-provoking blog argues that “we should resist our natural tendency to prepare too far in advance” especially in software development. Rather than carry along too many unused tools and excess baggage, Jeff admonishes,

Deciding too late is dangerous, but deciding too early in the rapidly changing world of software development is arguably even more dangerous. Let the principle of Last Responsible Moment be your guide.

And yet, something about the principle of the last responsible moment has always made me feel slightly uneasy. I’ve blogged about a related topic (just barely enough design) before. And be aware that in both my personal and professional life that I am not known as someone who plans things far out in advance. As a consequence I rarely use frequent flyer miles because I don’t anticipate vacation plans far enough in advance. I am not known to get to the airport hours ahead of my flight either. My just-in-time decision-making and actions have been known to make my travelling companions a bit uneasy. They prefer a not so tight timeline.

But what about software development? Well, if I find an approach that seems worth pursuing, I’ll typically go for it. I like to knock off decisions that have architecturally relevant impacts early so I can get on to the grunt work. A lot of code follows after certain architectural choices are made and “common” approaches are agreed upon. Let’s make a rational decision and then vet it, not constantly revisit it, is my ideal.

Yet I know too-early architecture decisions are particularly troublesome as they may have to be undone (or if not, result in less-than-optimal architecture).

So what is it about forcing decision-making to be just-in-time at the last responsible moment that bugs me, the notorious non-planner? Well, one thing I’ve observed on complex projects is that it takes time to disseminate decisions. And decisions that initially appear to be localized (and not to impact others who are working in other areas) can and frequently do have ripple affects outside their initially perceived sphere of influence. And, sometimes, in the thick of development, it can be hard to consciously make any decisions whatsoever. How I’ve coded up something for one story may inadvertently dictate the preferred style for implementing future stories, even though it turns out to be wrongheaded. The last responsible moment mindset can at times lull me (erroneously) into thinking that I’ll always have time to change my mind if I need to. I’m ever the optimist. Yet in order to work well with others and to produce habitable software I sometimes need a little more forethought.

And so, I think I operate more effectively if I make decisions at the “most responsible moment” instead of the “last responsible moment”.

I’m not a good enough of a designer (or maybe I am too much of an optimist) to know when the last responsible moment is. Just having a last-responsible moment mindset leaves me open to making late decisions. I’m sure this is not what Mary and Tom intended at all.

So I prefer to make decisions when they have positive impacts. Making decisions early that are going to have huge implications isn’t bad or always wasteful. Just be sure they are vetted and revisited if need be. Deferring decisions until you know more is OK, too. Just don’t dawdle or keep changing your mind. And don’t just make decisions only to eliminate alternatives, but make them to keep others from being delayed or bogged down waiting for you to get your act together. Remember you are collaborating with others. Delaying decisions may put others in a bind.

In short: make decisions when the time is right. Which can be hard to figure out sometimes. That’s what makes development challenging. Decisions shouldn’t be forced or delayed, but taken up when the time is right. And to help me find the right times, I prefer the mindset of “the most responsible moment” not the “last responsible one.”

Posted in Agile, Software Architecture, Software Design | 1 Comment

Agile Architecture Myths #1 Simple Design is Always Better

Over the next few weeks I plan to blog about some agile software architecture and design beliefs that can cause confusion and dissent on agile teams (and angst for project and program managers). Johanna Rothman and I have jointly drawn up a list of misconceptions we’ve encountered as we’ve been working on our new agile architecture workshop. However, I take full responsibility for any ramblings and rants about them on my blog.

The first belief I want to challenge is this: simple designs are always better designs. If you want to quibble, you might say that I am being too strict in my wording. Perhaps I should hedge this claim by stating, “simple design is almost always better”. The corollary: more complex designs are never better. Complex design solutions aren’t as good as a simpler solutions because they are (pick one): harder to test, harder to extend, harder to understand, or harder to maintain.

To break down the old bad habits of doing overly speculative design (and wasting a lot of time and effort over-engineering), keep designs simple. Who can argue against simplicity?

I can and will. My problem with an overly narrow “keep it simple” mindset is that it fosters the practice of “keeping designs stupidly simple.” Never allowing time to explore design alternatives before jumping in and coding something that works can lead to underperforming, bulky code. Never allowing developers to rework code that already works to handle more nuances only serves to reinforce ill-formed management decisions to continually push for writing more code at the expense of designing better solutions. What we’ve done with this overemphasis on simplicity is to replace speculation with hasty coding.

Development may appear to go full throttle for a while with thit absurdly simple practice, but for more complex projects, eventually any lack of concerted design effort can cause things to falter. Sometimes more complex solutions lead to increased design flexibility and far less code. But you will never know until you try to design and build them.

One of the hardest things for agile developers is to achieve an appropriate balance between programming for today and anticipating tomorrow. The more speculative any solution is, the more chance it has of being impacted by changing requirements. But sometimes, spending time looking at that queue of user stories and other acceptance criteria can lead you to consider more complex, scalable solutions earlier, rather than way too late. And therein lies the challenge: Doing enough design thinking, coding and experimentation at opportune times.

Posted in Agile, Software Architecture, Software Design | 11 Comments

Slicing and Dicing Complex Projects…

In a recent post, Johanna Rothman asked the question, should agile teams Develop by Feature, Develop by Component, or Some Combination? Well, in a nutshell, my answer is, it depends.

I have seen teams try different approaches to this problem. And there is ample experience out there to draw upon. As Julian Sammy points out in his remarks, “My experience is that the feature and component layers have several many to many relationships, depending on the level of detail you’re working at…If you are building a new feature… then you should be able to factor this [into several components.]” Yep, a big feature needs to be broken down into smaller, bite-sized chunks. And sometimes, those components can stand in relative isolation from each other. But if you are basing a feature on a common domain model, you may want to develop in a way that feature code interacts with a common domain model. That’s how followers of domain driven design approaches tackle this problem. So that one way to split up the work…one group works on building up a “core” of domain objects that other components that comprise the feature use. And in more complex projects there are even more layers of complexity. Your code that implements a feature may need to interact with other systems and pre-existing components and services. And there may be parts of a system that have “upstream” and “downstream” relationships with your stuff. It can get all quite complictated. It can get hard to keep a clear picture of relations between things in your head.

So it isn’t always the case that a group of people developing a feature are in control of their own destiny (in fact, they often are relying on components or other systems developed by people who are working far away).

One thing that Bernd, another commenter points out, is that managing the dependencies between can get quite complicated. My experience matches up with Bernd’s. Even though you may have a timeline with expected deliveries between components, it still can be difficult to manage. No matter how well you specify an interface for what you need, it is always open to interpretation. Even with tests and exemplary code to illustrate what you want…or what you are providing, the devil is in the details. That’s why people like to encourage developing code that exercises functionality that cuts across the systems and components you are trying to integrate. And if those systems or components aren’t ready yet, mocking is one way to get you ready to integrate. But still. It isn’t easy.

So while it is ideal to have control of a feature, on complex projects there will always be dependencies on other things that not totally under your control. That’s what makes life so interesting, and the role of agile architecture and looking at what lies ahead while keeping yourself firmly planted in today’s realities so challenging. And if you are working in an agile world you take every opportunity to test out the difficult bits before you lock them down. That’s both a challenge and an opportunity.

Posted in Agile, Software Architecture, Uncategorized | 1 Comment

This blog has moved

My old blog and contents have been converted to wordpress. You can find this new blog at wirfs-brock.com/blog.

I find that tagging and categorizing are a good way to organize my blog writings and like the features that wordpress offers.

Now that I have a fresh start, I plan on writing more….

-Rebecca

Posted in Events, Uncategorized | Leave a comment

Las Vegas….gambling on agile?

OK, I want a catchy title… But I also want to tell you about the upcoming Better Software Conference and Agile Development Practices in Las Vegas June 6-11 where I’ll be presenting a one-day tutorial on Writing Effective Agile Use Cases. No I am not co-opting Alistair Cockburn’s bestselling Writing Effective Use Cases….this title was suggested by the conference organizers. They think it is more catchy than what I proposed: Writing Agile Use Cases.

I hope to share with you effective techniques I’ve picked up for writing use cases in an agile development environment. While I am not a believer in writing for writing’s sake, I happen to find that writing documentation on agile projects to not be intrinsically evil. I’ve worked with several agile teams to trim down their project documentation, write effectively, and to focus on what matters to them. Not every user story should be part of a use case description. And not every user story needs to be documented. But I believe in the power of the written word when it is effective, streamlined, and to the point. And I find  that use cases that focus on usability and defining  user tasks to be well-received by agile teams. Especially if they are done in context with usability experimention, wizard of oz prototyping, and lightweight user interface specification. So come join me in Las Vegas.  Or ask me about agile use case writing workshops…where we hone our writing skills and write project-specific use cases.

Posted in Agile, Analysis, Events, Usability | Tagged , , , | Leave a comment

Draw a Tree

I often use a short, icebreaker to introduce design storytelling in talks and classes. I hand out an index card and ask people to draw a tree in 60 seconds. I’ve adapted this from Thiagi’s 99 second Draw a Tree exercise. I ask attendees to draw a tree, any old tree, and to be sure to autograph it as there will be a prize. At the conclusion of the exercise I pick someone at random to receive a small gift or book.

I have collected hundreds of drawings, some are very beautiful. Rarely I get drawings of bamboo.

Invariably one nerd who wants to win the prize and show off his computer geekiness draws a directed graph. After all, he doesn’t know the criteria I’ll use to choose a winner (none, it is a random drawing).

But most draw physical trees.

I get canonical tree shapes: mainly deciduous trees, with and without leaves, and a few conifers.


After I’ve collected the drawings, I ask how many drew roots and if so, why? If not, why not? Invariably, as Thiagi observes, most do not include roots, but some include roots or hints of root structures.

When asked why they didn’t draw any roots, invariably the answers is, “Because I drew what I can see. No need to show what’s below ground.” When asked why they included roots, those who did answer, “Because trees have roots.” Some software folks are very detailed and want to show everything. I’ve even received trees with tree parts labeled.

And there is my hook into the art of design storytelling. It depends upon your audience and the goal for telling your story whether you should include roots or not. There’s no “right” answer. Depending upon what your audience already knows and what you want to focus on, it is perfectly OK to leave out certain details.

The art of effectively drawing or describing any aspect of a software design, is to knowing what to leave out. It’s just as important to know what to omit as it is to know what to include. There’s always more detail. Effective design storytelling leaves out unessential details so that the important stuff can get emphasized.


Posted in Software Design, Teaching techniques | Tagged , , , | 2 Comments

Design For Test

It sounds straightforward. Write your test code first, then write code to pass that test. Don’t write an inch of code without writing a test first. That is what test-driven development (TDD) is about: Use tests to drive out the design and implementation. Rinse and repeat. Repeat many times a day.

I know a number of top notch developers who are masters at their craft. Yet they don’t daily program in a pedal-to-the-metal test-first-only write-the-barest-amount-of-code-to pass the test style. Yet they value testing. Testing, to them, is integral to programming. I asked a few of my programmer buddies who value testing what does it mean to design for test (I have my ideas, but I don’t make my daily living writing production code)…even if they aren’t TDD followers.
And the bottom line is this: code that is designed for test must continually be tested (not necessarily at the speed of a TDDer). If you want to make testing feasible, you often need to make code-under-test easy to isolate from its production environment, tunable, and measurable. Not easy stuff. Just like design flexibility, testing doesn’t come for free. It’s part of a disciplined development process.

Read more about Design For Test in my latest IEEE Design Column.
I’d like to hear your reactions…
Posted in Software Design, Uncategorized | Tagged , | 2 Comments

The Value of Design Documentation

Recently I asked students to tell me what kinds of requirements they start with and what (if any) design documents do they produce.

Several students said that they produced documentation just because it was part of their development process. As a consequence, they felt that the documents were rarely read, were hard to keep up to date with the real code, and were expensive to generate.
I know that everyone isn’t free to change their process…but if something is expensive to do and doesn’t add value, especially in this economic climate: look for a better, less expensive alternative.
My advice f is to keep the precision at a low enough level that you don’t have to keep updating it with every small change. Last year I helped one client develop a 2 page high-level view of the architecture for IT applications. On the first page was a component diagram. On the back was a high-level statement of each components’ responsibilities. While during development they produced other docs, these high-level overviews were intended to orient people who were going to maintain these applications. They were pleased when this high-level view was well-received by those developers.
Simply because a tool lets you reverse-engineer an implementation into detailed class or sequence diagrams doesn’t mean you should create lots of implementation-level diagrams. On another project where we used TogetherJ, we pruned sequence diagrams (to omit detail) so that business analysts could understand the basic flow w/o having to know everything. These edited diagrams didn’t end up in any permanent design document. Instead they helped explain our working prototype.
To be effective design documents have to communicate valued information to its intended audience. So if you find yourself creating documents that aren’t useful…well, think about suggesting cost cutting and process improvement ideas to your team and management. This is the right economic climate to suggest such positive changes.
Posted in Software Architecture, Software Design | Tagged | 2 Comments

Sustainable Design

In my most recent IEEE Column, Creating Sustainable Designs, I explore what it means to create software that can be maintained without too many growing pains. I have been intrigued by Christopher Alexander’s writings, particularly the first two volumes of the Nature of Order where he explains the properties of designed (or architected) things which have life and processes for creating life.

It is just as important to look at process of creating good software as it is to consider what properties make software habitable for those who have to maintain it and keep it alive. While I appreciate process (and I think the agile community has given us a lot to consider) I am more keenly interested in exploring what makes complex software “living”.
Alexander identifies these properties (or qualities) of living things: levels of scale, strong centers, boundaries, alternating repetition, positive space, good shape, local symmetries, deep interlock and ambiguity, contrast, gradients, roughness, echoes, the void, simplicity and inner calm, and non separateness.
It can be easy picking to draw certain connections between certain “good” software design properties and Alexander’s list. For example, good shape, as others have pointed out can be a matter even as simple as properly indented a method. Or it can be more profound than that–leading you to break up a method into substeps and invoke helper methods, just to keep every step at a similar level of abstraction. I’m only giving you a taste to see whether you are interested in exploring these ideas further.
If you are,  read my column, and also take a look at the C++ Report article by Jim Coplien on Space: The Final Frontier, which introduces Alexander’s notion of centers and how they relate to software structure, and peruse several very good blog entries by Regis Medina.
And if you are interested in exploring these ideas further, perhaps by taking a deep look into working code or frameworks or software that you consider to be particularly alive (or not)… let me know. I am considering finding a venue where software developers and designers and philosophers could concretely explore Alexander’s properties more thoroughly. I am not just satisfied to make those simple, easy connections and call it good. I want to challenge our best designs and see whether Alexander’s properties really do apply (or if we have some other properties that are more relevant).
Posted in Half-baked Ideas, Software Design | Tagged , , , | 4 Comments