Monday, 30 May 2011

I've come across the idea that because cross-functional teams need a variety of skills, members of the team should aspire to be generalists. I think that is overstating the case somewhat.

Agile teams need to be able to handle workloads requiring varying mixtures of skillsets. In order to cope, teams need elasticity, that is they need to be able to temporarily boost their capacity in a particular kind of work as the situation requires.

This can be better achieved by a mixture of flexibility and focus than by either radical specialisation or radical generalisation.

Specialisation has the obvious drawback that if the specialist in a given area is at full capacity the team cannot take on any more of this kind of work. This leads to the situation where some team members aren't fully utilised but the team cannot commit to taking any more stories to "done done" in the current iteration.

Total generalisation doesn't produce idle team members, but it does prevent a team from reaching its maximum possible potential. Software development is full of difficult and technically-specific problems that may not be understood by someone who has not deeply immersed themselves in that discipline. Furthermore, it's hard for someone who isn't fully comfortable with a domain to coordinate others at the same level.

I prefer teams where there is an expert ready to take charge in the face of any given challenge and who can rely on the rest of the team to fall in behind them. This happens best when team members are specialists in their own discipline and generalists in everything else.

To return to the metaphor in the title of this post, effective agile teams have a definite shape but they have enough elasticity to absorb the shocks of atypical workloads.

Logically, Phil's maxim that "what’s easy to change in the business model should be easy to change in your architecture" can only be achieved by structuring teams around domain concepts and avoiding cross-cutting concerns.

Sunday, 15 May 2011

Broadly speaking, programming languages can be categorised as either imperative or declarative. This post will explain the difference, and also argue that a declarative approach to management leads to better outcomes.

Imperative programming

Imperative programs are lists of commands. Here is a piece of C code that tells the computer how to make a meal based on a recipe. Get a bowl, start at the first ingredient, add and mix ingredients one at a time and stop when there are none left:

For some recipes it doesn't matter what order ingredients are added. It wouldn't make a whole lot of difference to your pancakes batter if you add the milk before the eggs or the other way around. But this code doesn't trust the computer to decide when rearranging ingredients is safe; they must be added in the exact order that they appear on the list.

Declarative programming

Prolog is a kind of declarative language known as a logic programming language. I write Prolog code by declaring facts (Susan is Mark's parent) and rules (a grandparent is a parent of a parent):

I didn't describe how to arrive at those answers. I merely provided the necessary information and left the rest up to Prolog. If someone changes details in Prolog's algorithm it won't affect my program so long as it continues to interpret facts and rules in the same way. There are many different kinds of declarative programming language but they all focus on what needs to be achieved and leave the how to the implementors' discretion.

If the story says "As a user, I want the system to know my favourite colour, so that the site can be personalised to suite my aesthetic taste", then the team are free to bring their expertise on the problem. The solution they come up with might even surprise the person who originally came up with the story. In the agile world, we call this "delighting the customer".

On the other hand, imperative management is very specific about exactly how the things must be done. To follow the recipe example above, workers in a fast-food chain might be given exact steps on how to put together a hamburger.

There is a place for both imperative and declarative programming. Declarative programming is a good choice when it's important to make intent very clear or when the computer is in a position to make better optimisations than the programmer. Imperative languages are often the only sensible choice when the how needs to be tightly controlled e.g. to ensure high performance in a video game.

However, there is very little justification for imperative management. The only time that its helpful to give a team the how is when you believe that they would come up with a worse solution than you. If you think that's true, you're probably either wrong or you haven't properly trained your team.

I'm sure there are rare cases when imperative management can help the business. In the fast food example, the fastest possible way to assemble a burger might not be independently arrived at by every part-time employee. Just like a C++ programmer might use her detailed understanding of a PS3's hardware to force it to behave in a certain way, central management might find it advantageous to promulgate an optimised burger production process that's faster than what employees could come up with themselves. But as a general rule this doesn't happen, because while computers are naive and unable to show initiative, your employees are not.

Imperative management is micromanagement. Declarative management is empowerment. And since your employees are (hopefully) better at their jobs than you are, empowerment is more likely to achieve the results you are after.