Strategy, Tactics & Logistics (in software development)

Created 9th June, 2006 11:02 (UTC), last edited 26th February, 2007 10:56 (UTC)

Hopefully everybody is already familiar with what the terms strategy, tactics & logistics really mean. If you you're not 100% sure then read Strategy, Tactics & Logistics (in fact best skim through it even if you do think you already know).

Before I start there are two things I want to point out right from the off:

  1. If you've written any software you're already thinking in terms of strategy, tactics and logistics; you just haven't been labelling your thoughts in that way (yet).
  2. There is a continuum between the three terms. Don't get too het up arguing whether any one thing is logistical or tactical, or, tactical or strategic. This is a way to help you think, not a way to help you argue.

OK? Good.

So, before we go any further there is one other thing we should do, which is to broad-brush what these terms mean¹ [1Just in case you ignored the guide with the detailed meanings.]:

  • Logistics—As the name almost implies, these are things that can be worked out logically. There are good and bad answers and there are metrics for finding which is which.
  • Tactics—These are things that work in certain situations. If the situation for a tactic is wrong then it won't work. The right tactic in the right situation is a perfect fit. The wrong tactic in the wrong situation makes you look like a muppet (or gets you killed if there's firearms involved).
  • Strategy—These are the plans and designs that you make before you start to do something, or more generally, before you start to tackle your next task.

You may reasonably be wondering why this matters. If you're already thinking about these things then why can't you just go off and read something else? This is a mistake.

When you're thinking through an problem the more ways you have of framing your thoughts and decisions the more likely you are to get a good solution. If you can only frame your thoughts in one way then the chances of you avoiding all the pitfalls isn't is high as if you can frame your thoughts in many different ways and on many different levels.

Logistical concerns

What's the difference between ++p and p++? If you know what you're doing you'll already be using the first when incrementing loop variables (at least of iterators in C++). This is an example of logistics at work. At heart logistics are those things that always work to make programs better, smaller and faster.

The scope of these decisions is generally a few lines of code or the choice of a data type for a single attribute. Normally logistical questions have a single answer that is optimal. When you hear somebody say “That's an implementation detail”, what they really mean is that, for them at least, they consider it a logistical item and there should be a single optimal answer.

The nice thing about the logistical part of the problem is that this is the part that computers are good at. Every year that goes by more and more logistical matters are dealt with entirely by the compiler or language.

The fact that there should be an optimal answer doesn't mean that the answer is always easy to find. Sometimes you can get away with a good enough answer and not worry too much about it. That depends on the context though and that leads us on to tactics.

Tactical issues

This I think is the area where things are most interesting. For example, whether you should implement accessors directly, or abstract them into helper classes is a tactical consideration.

There are thousands of these techniques that every master programmer knows and just as importantly they know when to apply them and when not to. Do you solve a problem recursively or do you convert the algorithm to a loop?

Tactics are by their nature situational. If you apply them in the wrong situation you get errors at worst and poor software at best. Apply them in the right situation though and you can build elegant software that does what it is meant to do with a minimum of problems.

The journey to being a master craftsman in software development is to learn as many of these tactical plays as you can and then to master the situations you should use them in. This means trying them all, not just repeating the one that worked last time.

Many of the rules that we come across in software development fall at this level. This is why we need to understand the rules in order to write better software. Merely following them will probably be OK, but if we actually understand what is behind the rule we can see the situations that the tactic doesn't work in.

Strategies

These are questions to do with structure of the program. They are your plan for the approach you will take.

They include answers to questions about language choice (C++, Java, Javascript etc.); which platform (Java byte-code, Linux, Windows); how to deliver the application (web via AJAX, HTML/XHTML, desktop); will there be an API; if so how will it be called?

Here you enter the realm of strategy. In many ways strategy is woolly. But if there's something that you're thinking of before you start to code then it's probably strategic.

If you know a lot about databases, but nothing about web services then a framework that takes the tactical and logistical issues of HTTP out of your hands and can build HTML forms is your best strategy. If on the other hand you know nothing about databases but everything about AJAX then use a framework that makes the tactical and logistical issues about database communication, transactions and SQL statements for you.

Neither of these will make the best tactical or even logistical choices for you, but they will both give you better results than anything you'll be able to come up with no matter how agile your development process.

There is a deep point here and that is that the ability of you and your team matters and is an important input into what problems you can tackle, and how you should tackle them. If the problem looks intractable to you then it probably is, but that doesn't mean it can't be solved by somebody else. If you've never tackled a problem of a certain nature before then diving in is a good learning strategy, but a poor strategy to use when the system has to work.

Accidentals and essentials

There is also a correlation here with Frederick Brooks' notions of accidental and essential difficulties² [2No Silver Bullet: Essence and Accidents of Software Engineering]. His essential difficulties revolve around formulating the strategy for the development process, whereas the accidental difficulties are the logistical problems. This leaves the tactics out of course. They're the bits that we hope will become logistical with the aid of better tools, but no matter how hard we try there are always going to be strategic issues that need intelligent input.

Better frameworks, better languages and better understanding will help to move problems from strategy meetings, to tactical worries and on to logistical answers. The supply of strategic problems is of course infinite and no matter how good our tools and understanding gets there will always be something new that will require us to develop new strategies, work out how to make it tactical and then throw it into a new language or framework so it's logistical. This gives you time to start thinking about strategy for the Next Big Thing™.

Remember that if you know what the input data is going to look like then you can move things into the logistical arena that somebody writing more general software would have to leave at the tactical level. This is true for all levels. The better we understand the problem domain, the system inputs and how it will be used the more we can push from strategy to tactics and from tactics to logistics. Each problem must still be weighed and judged on its own merits.

Appendix: Towards a formalism

I've been wondering whether, for software development at least, it isn't possible to formalise these three levels somewhat.

  • Logistics can be worked out before the software is run. The metric is known and the behaviour of the software is sufficiently well known to be able to give a definitive answer before the software is run. These are the things where we can look up an algorithm and get a proof that it's the best we can get. Not getting this right is plain ignorance.
  • Tactics can in principle be worked out, but we don't have the information whilst we're writing the software to know which is the right tactic to use. We have to write the software and run it in order to get the metrics to tell us whether or not we made the right choice. We learn to get this right through experience.
  • For strategy we cannot, even in principle, evaluate the answer. There aren't any metrics we can use that will tell us. There is a never ending battle to try to turn strategy into tactics (and even better into logistics), but there'll always be a need for programmers to work on the strategy even as we palm more and more of the logistics off to the computers. Normally the strategy we use says as much about ourselves as it does the problem.

I'm not saying that these levels will be immune from considerations about the specific problem domain. If you know what the input is going to be before the software runs then you can move tactical issues to logistics that a developer without that understanding can't. I don't see that this affects the formalism at all.

Comments? Thoughts?


Categories: