2 Surprising Truths About The Iron Triangle

Project management 101 teaches that, when managing outcomes, you cannot alter scope, schedule, or cost (resources) without affecting at least one of the other dimensions. This interrelationship is known colloquially as the “Iron Triangle.” Sometimes we put “quality” in the middle to show how it is unavoidably shaped by choices on the other constraints:

Image credit: John M. Kennedy T (Wikimedia Commons)

Lots of Dilbert cartoons derive their humor from the unwillingness of the Pointy Haired Boss (PHB) to acknowledge this relationship. These cartoons are funny because they are so eerily similar to conversations we’ve all had, where someone wants us to deliver ultra-high quality, on a limited budget, in an aggressive timeframe, with a boatload of features.

It ain’t gonna happen, folks. We engineers are clever, but we’re not magicians. Triangles don’t work that way.

You’ve learned some good principles when you can articulate this geometry lesson.

But there’s more.

Truth 1: Scope is a trickster

Many well meaning managers and executives understand this trilemma, and they distance themselves from Dilbert’s PHB by acknowledging that something has to give. “I pick scope,” they’ll say. “We absolutely must have the product before the summer doldrums, and we only have X dollars to spend, but I’m willing to sacrifice a few features.”

This can give product management heartburn–feature sets sometimes hang together in ways that make slicing and dicing dangerous. An airplane that’s good at takeoffs but that can’t land is unlikely to be a commercial success. Good product managers will point this out, and they’ll be right.

Continue reading

Metrics, Plumb Lines, and System Thinking

Friday morning I was at a seminar taught by Jason Taylor, CTO at Allegiance. We were discussing how dev team velocity and product quality can compete for our attention; sometimes we trade one for the other. Jason mentioned that he’s a fan of competing metrics, and some neurons connected in my brain.

Plumb line suspended from the center point of multiple balancing legs. Photo credit: suttonhoo (Flickr)

I’m a big believer in measurement. As the old adage goes, you can’t improve what you don’t measure. Next time someone urges you to change a behavior, or tells you she’s going to, ask what measurement of change is being proposed. If you get an unsatisfying answer, I predict you’ll also get an unsatisfying outcome.

I’m also a big believer in balance, as I’ve written about before. Good software balances many considerations.

Besides these existing predispositions, I’d recently read a blog post by Seth Godin, cautioning about the need to choose wisely what we measure. And I’ve been digesting The Fifth Discipline, by Peter Senge, which advocates wholistic, systemic thinking, where we recognize interrelationships that go well beyond simplistic, direct cause-and-effect.

All of these mental ingredients Continue reading

What Is “Good Code”?

This is one of those questions that I often ask when I am interviewing a computer programmer job applicant, trying to get a sense for an engineer’s maturity with the craft. (And for the record, I don’t think the question has a “right” answer. Certainly there is no ideal one-sentence response.)

Sometimes I get answers like this:

  • “Whatever gets the job done.”
  • “Whatever sells.”
  • “Whatever solves the customer problem.”

Answering tough interview questions. Photo credit: bpsusf (Flickr).

Such answers tell me that an engineer is practical, business-aware, and customer-focused–all useful traits. Pragmatism is usually learned in the economic school of hard knocks, and it’s a critical perspective that should never be forgotten. But I don’t get a warm fuzzy from pure pragmatism; it lacks vision or love of craft.

Another kind of answer focuses on cleverness:

  • “I wrote a burst sort once that could beat stdlib qsort. It’s counterintuitive, I know, but the way burst sort works cache…”
  • “You wouldn’t believe how much you can say with a 3-line statement in python…”

An engineer with this type of perspective also has praiseworthy qualities–an appreciation for elegance, a desire to achieve. But I find these answers unsatisfying as well. For one thing, the statements are lonely; notice how little they imply about who will build upon or use the finished product. In this vein, I love Martin Fowler’s warning in Refactoring:

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”

I’ll also include a “miscellaneous” response category, which encompasses stuff like:

  • “Good code has to be scalable, make efficient use of resources, optimize for good performance, …”
  • “Good code is maintainable and testable.”
  • “KISS — keep it simple, stupid.”

All true (the first statement less than the other two, IMO), but all less than fully satisfying.

So what answer would impress me?

Albert Einstein supposedly said, “Make things as simple as possible, but not simpler.” Well, I think good code is quite a complicated subject, and the first thing that would impress me is an acknowledgement that I’ve posed a very difficult question indeed.

Since I’ve already mentioned one of my favorite quotes about simplicity, I think I’ll mention the other here, as well. Oliver Wendell Holmes: “I would not give a fig for the simplicity this side of complexity, but I would give my life for the simplicity on the other side of complexity.”

Holmes was talking, I believe, about wrestling with a difficult, multifaceted problem, and distilling it down to its essence only after all its dimensions are fully understood.

I’m going to post a few observations on what I think constitutes good code in coming days. These will be glimpses of zen that I’ve occasionally stumbled upon on the “other side of complexity” as I’ve wrestled with the craft through my career.

I’ll be curious to know what you think, as well.

(Read more posts in my “What is ‘Good Code’?” series…)