Choose Your Constraints

A while back I published a few Tweets about constraints. They seemed to strike a chord with others, and I want to develop the point a bit more.

So let’s start with this: What are some constraints you feel in your day-to-day coding? Which factors are limiting your ability to produce new, shippable features? Consider the following list:

Take a moment and check off the 3 biggest pain points in your current job.

You’ve selected:

    Hold that thought; let’s talk for a moment about the most significant force behind your (and all developers’) frustrations, and how it underlies the factors you’ve chosen.

    The Triple Constraint

    The Triple Constraint, also known as the Project Management Triangle, is well-known as a classic line developers tell overzealous managers:

    We can build it with every feature, on time, and on budget. Pick two.

    The Triple Constraint sets up a fundamental tension between three factors:

    1. Time (how quickly the project is done)
    2. Cost (how much it costs to complete the project)
    3. Scope (how many features are built, and how well)

    Any time you make greater demands in one aspect, at least one of the others will have to give. If you reduce the time for the project, you’ll need to pay more or (more realistically) cut scope. Want to save money? Cut scope, or hire developers who will do it more slowly. To increase the scope, pay more, or better, developers, to work on it for the same amount of time, or increase the length of time allotted for the project.

    Let’s see how the Triple Constraint applies to the problems you’ve selected:

    So it looks like . With that in mind, let’s think about a more active approach to controlling and choosing our constraints.

    Constraints: A Choice of Which, Not Whether

    The point of the Triple Constraint is to emphasize that constraints will exist on every project, and we are responsible for managing them realistically. There is great temptation to assume that with extra effort we can cheat the system and push for a better outcome on all 3 constraints. That’s just not possible.

    However, by acknowledging and embracing our constraints, we can maximize the outcome. We cannot build every feature, on time, and on budget. But we can build the right set of features, given the right amount of time and an appropriate budget.

    Let’s think about this in the context of the issues you selected.

    The main point here is that each of Cost, Scope, and Time constraints will get the best of you, unless you actively acknowledge the conflict, and make sure your efforts reflect the true business priorities. Attempting to maximize all three is impossible and will usually lead to significant shortcomings in all three areas.

    Adding More Constraints

    This is the Tweetstorm (yes, my own) that originally got me thinking:

    Now that I’ve thought things through more clearly, let’s summarize using the terms above. You already work within constraints of Cost, Scope, and Time. If you ignore the competitive nature of those constraints, you will overwork yourself, fail to deliver the entire Scope, miss the deadline, or—even worse—all three. This will become the de facto mode of operation, much to the consternation of yourself, your colleagues, and your managers. Worse, you will take on the Cost of long-term technical debt because it allows you to expand Scope and minimize Time in the short term.

    The only solution is to embrace the fact that you just can’t do everything, and take on constraints that will safeguard you from the poor decision-making that brings on long-term troubles.

    The four constraints I recommend budgeting for, as mentioned above, are:

    1. Testing: Insist on meaningful test coverage. There are advantages to writing your tests first, but at least make sure you end up with solidly tested code.

      • You will know your code works, and it will be much easier to change or extend later without breaking everything.
      • It’s hard to know you’ve accomplished the appropriate Scope without a reproducible test, and not testing increases the Cost of adding features later.
    2. Pairing: Don’t let a sprint go by without finding an opportunity to pair on something, anything.

      • Pairing is not always the best use of resources (you might say it’s double the Cost), but often the synergy of two coders talking things out nets an overall gain in productivity.
      • Pairing also provides a host of benefits for the long term, in terms of team relationships and knowledge sharing. Which brings us to the next point…
    3. Knowledge Sharing: Make time in your workflow to share knowledge, both formally and informally.

      • Meet weekly with your team and have someone present their recent work. Eventually everyone will take a (temporary or permanent) vacation, and someone else will need to fill their role. Pay down the Cost of a weekly hour-long meeting, so your team isn’t frozen when one person takes a much-needed break.
      • Look for opportunities to pair junior and senior developers together. Or if someone is unfamiliar with part of the codebase, assign them a ticket that requires them to learn it, and designate a knowledgeable pair. The stronger each member of your team becomes, the more quickly you can build new features in a stable fashion.
    4. Learning: I expect this to be controversial, but here goes. Make time in your workday for something code-related that has nothing to do with your work. Try out a new language or framework. Write a script to automate something at home. Read an article from one of Peter Cooper’s newsletters or watch a talk on Confreaks. Follow the Twitter account of a developer you respect and read what they post. Broaden your horizons in code, and you’ll find that some of your most brilliant ideas at work will come from your explorations. You can’t be inspired without inspiration.

    The crazy thing about these practices is that if you constrain yourself for long enough, they become second nature, and you don’t notice the time they take up. Eventually, your budget will automatically include these activities. Yet you will be able to crank out features at a quicker, more stable pace, precisely because you are taking the time to invest in yourself and your code.

    You will also notice a greater sense of team cohesiveness. These practices encourage the team to work together, to learn together, and to help each other grow in capacity to produce excellent software. These practices bring out the synergetic relationships that make team-built software qualitatively better than software produced by individuals.

    Sometimes, it will be difficult to get buy-in from the more business-minded stakeholders in your company. For this reason, make sure to couch the conversation in terms of risk avoidance and long-term business objectives, which honestly should be your goal, too.

    A Call to Action

    Let’s end with a challenge, shall we? Commit to one—just one—of these four practices for the next two weeks. Then let’s hear some feedback about how you did, and what type of impact it had on yourself, your code, and your team.