The Art of Constraint

Adam Lammiman
11 min readNov 5, 2021

Constraint

noun: a limitation or restriction

This is the third article in a series that began with the exploration of the foundations of my current software development philosophy. The second article focussed on the first pillar language, this article looks in more detail at the second constraint.

Constraint can often seem like a dirty word, to feel constrained is not a term often used in a positive sense, and yet we are always operating under some form of constraint and it could be argued that it is far more our constraints that bind us together as a society than anything else. We may not like to feel we are being constrained, and we do tend to romanticize the rebel on the edge of society (at least in the West), but I think most of us would rather not meet someone who ‘lives outside the normal constraints of society’ in a dark alley on the way home from the pub.

For me the deciding factor for me is choice and intent. A constraint is positive if either you choose how and when you apply it or its benefit can be clearly explained to you. If you can adapt it and choose when it is appropriate, if you understand its rules and can feel you gain something positive from applying it.

Negative constraints on the other hand are those that are applied to you, or that you don’t understand and feel you have little choice in. Rules handed down from above where you have little input or say, where you must apply them even if you feel they are completely inappropriate.

Equally bad are rules you happily follow because that’s the way we do things, with little analysis, self-reflection, or opportunity for improvement.

The discipline of the constraint

There are several stages we need to go through in order to gain an understanding of any technique and we can’t use shortcuts otherwise we miss important lessons.

Firstly Rules have to be lived to be understood, when you’re taking on a new skill or you want to understand it then find the rules and force yourself to follow them to the letter.

You will never fully understand something like Test Driven Development if don’t make yourself write your tests first, and resist that urge to ‘spike out some code’. You won’t ever really understand user stories until you religiously apply INVEST for a while.

As your understanding grows you will find that you start to internalize the rules and their lessons, they’ll take on depth and meaning, you’ll understand where the limits are.

At this point you have reached a conceptual level where the constraint has become part of your thought process and the strict application of rules become less important.

If you’re a fan of martial arts and martial arts movies then there’s a particular quote from Bruce Lee you’re probably familiar with.

  1. A punch is just a punch
  2. A punch is no longer a punch
  3. A punch is just a punch

In that quote he’s pointing out that at first when learning a martial art you see all punches the same, then you start to understand there’s technique and skill associated with punching you never understood before and finally, once you’ve internalized those lessons, you are back to just punching.

You may have dropped the analysis of the second stage when you reach the third but your punch will be considerably different than that it was at the first.

However you cannot reach that third stage without the hard and rigorous slog of the second, neither can you without applying the ‘constraints’ of technique of form in that stage.

This applies equally to any skill, you have to put in the work and understand the rules of the game before you can bend or break them.

So let’s look at a few examples of applied constraints in software development and development teams and see if we can identify where the benefits are and watch out for the pitfalls.

Constrain your code

Write your tests first

Test Driven Development is a technique that has been around for over 20 years but I still find I have variations of this conversation quite often in interviews:

‘Do you practice TDD, Test Driven Development?’

‘Yes’

‘Great, so on the coding test we asked you to complete did you write the tests first?’

‘Erm, well no I just wanted to get something working so I added the tests in afterwards’

In case you’re thinking well that’s a bit unfair in that sort of test, I go out of my way to make sure people understand I’d rather see good tests than a finished application and yet that conversation comes up over and over again.

Now there is a whole other article to spin out here but the long and the short is that the simple constraint ‘write your tests first’ is something that has a great depth which you’ll never understand if you don’t follow the constraint.

The problem I think comes from the focus on the ‘tests’ and not the actual constraint which is ‘write them first’. That second part is the key, when people focus only on the test then a number of antipatterns begin to appear, this video lists out some good examples.

This constraint is not about test coverage, smaller commits, or more reliable code. All of these things are a consequence of following the constraint but, for me, they are not the main reason.

Writing the tests first is about framing the right questions, it’s about breaking a problem down into smaller more manageable chunks that can be tackled, understood and then often deleted and started again. It’s stimulating and streamlining the creative process, like an artist sketching ideas on a pad to try and understand what the final piece is going to look like.

Tests first give you a way of framing that process that is inherently missing if you try and do it the other way round.

All of that comes from the application of that single constraint, I will write my tests before my code.

Object Calisthenics to build coding muscle

So this is an example of using constraint as an exercise to improve but not as a rule to live by. Object callisthenics is a series of strict rules applied to your code designed to force you to think about the way you write your code.

They are as follows:

  • Only One Level Of Indentation Per Method
  • Don’t Use The ELSE Keyword
  • Wrap All Primitives And Strings
  • First Class Collections
  • One Dot Per Line
  • Don’t Abbreviate
  • Keep All Entities Small
  • No Classes With More Than Two Instance Variables
  • No Getters/Setters/Properties

I’m not going to go into each rule here, this article does a good job of explaining them all.

Would I always write my code following these rules? Absolutely not.

Do I feel that spending a few hours bending my brain trying to not use the else keyword and no more than one level of indentation on some pet project or test code is worthwhile? Most definitely.

The constraint here is dependent on context, by choosing to apply it at the right time I am improving the way my brain thinks about problems. By choosing to apply it at the wrong time I’m guaranteed to get thrown out of my team.

INVEST in User Stories

As I mentioned before in the partner article in this series, user stories are a technique of using language under certain conditions of restraint. The constraints here like those with TDD are primarily about creating boundaries to help guide both the author and consumer towards a better outcome.

The INVEST formula is a commonly used set of principles to write stories by. As before with TDD there is a whole other article here, but a brief overview is as follows:

  • Independent — stories must be atomic and verifiably independent pieces of value.
  • Negotiable — state the problem clearly, don’t define the solution. A story is a placeholder for a conversation, not a placeholder for a task you’re telling someone to complete.
  • Valuable — a single piece of end to end value, a story once completed should ideally be independently verifiable, it should be a vertical slice of work not a horizontal one (‘create database’ is not a story, create a form to capture name and address in order to get more customers is).
  • Estimable — Personally I don’t judge this as timescale or even story points, but a team should be able to judge its complexity and feel comfortable that they understand the work needed to complete.
  • Small — this is typically translated as ‘fits in an iteration’ though I feel that is slightly dangerous as it can lead to teams breaking the ‘V’ rule in order to meet the ‘S’ rule. I feel ‘small enough to be understandable’ is a better judge. Ideally you want it done in a sprint and you want to always aim for that but given the choice over Value and Small I’d always choose Value.
  • Testable — Acceptance criteria should be written in a way that leads to the tests you will need to verify the work.

Now sometimes this is hard and it’s tempting to fall into the habit of breaking work functionally because it seems this seems easier. But that is the point of the constraint, to force you to break old habits of thinking, to make you see things in a different way.

Constrain your process

The practice of Lean software development as popularised by the Poppendieck’s in their series of books is an interesting example of constraint, in that the Lean philosophy uses constraints to reduce constraints.

Based on the manufacturing process popularised by Toyota it has a focus on maintaining flow in the system. With the idea that reducing batch sizes of change and focussing on ‘single piece flow’ as an ideal state will create the most efficient system.

Though it’s often linked to Agile methodology I think their focus is slightly different. Traditional Agile uses techniques like timeboxed and immutable sprints to limit scope to an achievable result in a set period of time, while Lean is about creating and managing a continuous flow of unimpeded change.

The big thing in Lean is minimising waste, waste being bottlenecks in the system or repeated work, known as cycle time. Your focus is always on minimising the change, removing impediments to change further down the chain before adding more things in and reducing the amount of repeated change.

The idea behind this is that the more change there is then the more likelihood there will be mistakes and thus waste (for instance work cycling through the system multiple times).

Lean uses constraints like ‘WIP’ Work In Process (or Progress) which limit the number of concurrent things being done at any one time. The idea of small batch sizes and ‘single piece flow’ is that it is more efficient to maximise the throughput of one small change than to try to move as much through the system as you can in big batches.

So for instance my team uses a couple of constraints or rules that we follow. No more than 4 stories in any one column (WIP limit of 4) and ‘Pull from the right’, anything to the right of the board takes precedence to that on the left.

So if anyone needs something to do on the team then they need to answer these questions in order:

Can I help release something to production?
Can I help a story get accepted?
Is there anything I haven’t worked on that can be reviewed?
Is there anything in play I can help with?
And finally, pull in a new story.

By using these rules to focus on keeping the board clear you allow work to flow out once it’s complete.

Constrain your Team

Agile has risen to be a popular organizational model in the software development world because of its stripped-back approach and reliance on individual responsibility and ‘self-organizing teams’, a definition of Agile could be ‘anarchistic principles applied to team and project management.

Though Agile does not share the pollical aims of actual anarchist ideology (agile teams are unlikely to don balaclava's and start smashing up the office canteen. Unless you deny them coffee.), it does share the core values of a bottom-up organization and social contract that define some anarchist thought (I’m not the only one who’s noticed this by the way ).

The important thing to understand is that ‘self-organizing teams’ does not mean ‘no one is organizing this team’ or ‘there are no rules’. Contrary to popular belief anarchism isn’t about the removal of all rules, it’s about localizing the rules as much as possible. Any group left to their own devices will devise rules, will organize into hierarchies, but there’s no guarantee those choices will be healthy or sensible without the ability to reflect, to learn and without direction.

I’ve been on plenty of teams where they’ve ‘self-organized’ into a bickering mess with teams within teams that have very different and conflicting approaches. It does not make a healthy environment.

Ideally the direction and reflection in an Agile team comes from the team themselves and is not externally enforced, the team decide their rules and then should constantly revise and adapt them. However teams have different levels of maturity and different dynamics and a team lead has to be able to recognize where a team is and act accordingly and sometimes, sometimes (at the risk of sounding like I’m contradicting myself) constraints and rules of behaviour have to be imposed in order for lessons to be learned.

In his book Elastic Leadership Roy Osherove identifies three team phases: Survival Phase, Learning Phase and Self Organizing phase.

‘Survival phase’, everything is on fire, you’re constantly reacting to problems and fixing the last thing that broke. It can also be represented by a relentless drive to get things out the door without the space to reflect, improve and build. Or a team that is pulling against each other and fighting itself, not working as a team. Or all of them together.

In these situations a team needs what Roy terms ‘command and control’. Clear direction and strictly enforced constraints from someone with authority in order to break this cycle.

In the ‘Learning Phase’ the team has started to get things under control and now needs guidance on how to grow and develop. It’s about building time and structure to allow them to become and value being self-reliant.

The trick for a lead in this situation is how to move out of command and control’ to this phase. It’s easy for the leader to get stuck in self-important ‘telling people what to do’ mode and for the team to stay in the ‘tell me what to do’ mode.

At this point it’s about moving ownership of the constraints imposed away from ‘do what I tell you for your own good’ towards ‘I choose to do it because I can see it works’ and ‘how can we do this better together?’.

‘Self Organizing’ phase, is where a team is truly self-reliant where its practice and ethos are so ingrained that it can grow and develop and deal with problems as they arise, without much input from anyone else. This is a rare and hallowed place, more of a journey than a destination.

Now the important thing here is that the constraints start as a template of what good looks like, defining it and then setting boundaries of what is and isn’t acceptable (basically like having children if I’m honest). This then should grow into something that the team own and manage themselves.

In the beginning, if you are dealing with a team in the survival phase you are forcing people to do what they’re told. The difference is however that you’re living it with them and hopefully emulating the behaviour you expect from them, as opposed to handing down rules from on high.

Gradually, as the team can see the benefit of working with not against each other then the team should start to own and define its own rules.

Problems arise when people expect the ‘Self Organising’ phase to magically appear if they leave a team to their own devices. Don’t expect ‘good’ to form by just standing back and letting everyone get on with it, this is the team equivalent of skipping to the third punch or potentially ‘Lord of the Flies’ enacted in the office.

Even if you are not starting with a team in the Survival Phase people still need boundaries, direction, purpose and a team drive that’s more than just the next story on a backlog.

Conclusion

Don’t fear restriction, constraints are tools for learning. By restricting your options you can increase creativity and force yourself to think in new ways. Restriction can be a road that leads to freedom if you learn to embrace and use it.

--

--

Adam Lammiman

Making software is a creative pursuit, not just a technical exercise. Exploring the best techniques for its development.