Set-based design in software

Last year at the Lean and Kanban Benelux conference I attended a session by Michael Kennedy: Set-Based Decision Making: Taming System Complexity. Watch that video, where he explains the way that Toyota uses set-based design to be innovative without risk to the schedules of their new product development projects. I thought that was a very interesting subject, and left thinking about some of the questions Kennedy posed on the applicability to software.

Skip forward half a year, and you find me having just read Product Development for the Lean Enterprise, Kennedy’s book that describes the advantages of Set-Based Design, but closely links this to the concept of a knowledge driven organisation. The book is in the form of fiction: a ‘Business Novel’, I think the term is. I’m not overly fond of that format, but must admit that it worked well in this case. For this post, I’ll focus on the treatment of set-based thinking. The book talks just as much or more about the knowledge driven organisation and forms of change management that are compatible with it, but that is material for another time.

What is set-based thinking?

Set-based concurrent engineering, as the book calls it, is distinct from concurrent engineering, where different parts of the product are built concurrently based on clear requirements and specified interfaces. The set-based approach doesn’t just create the separate parts of the product concurrently, it ensures that there are multiple options for the separate parts of the product, and combines those options at as late a stage as possible (responsible?) to form the product.

Why is that a good thing? Well, the book gives a great example of building a new bicycle. A bicycle has various components: a frame, a drive, brakes, suspension, wheel seats, etc. If you are free to combine those parts is various ways, you have many different options of building a bike. That also means that if you develop new versions of all those parts, there are high risks of failing with at least some of them. That means that there has to be a trade-off: innovation against the chance of success for a new product development project.

As you can see in the picture above, the set-based approach avoids this trade-off: by working on different options for each of the parts, the risk of one of the parts not delivering becomes less. If we combine that with an approach where a safe, known to work version of the part is included, then failure of the project becomes very unlikely. This allows you to take more risk, and thus invite more chance of innovation, for the alternative versions of that part.

This is (as is true for large parts of the Lean world, even if we call it ‘knowledge based’ instead of ‘lean’ product development) based on the way that Toyota works in product development. An example from them that Kennedy mentions in the talk above(just in case you haven’t watched that yet) is that of the Toyota Prius. There were a number of innovative components in that car: the hybrid engine, the transmission, etc. Toyota developed multiple versions of those components, where some would have been initially developed for earlier cars, but perhaps had not been included because the technology wasn’t quite ready. Toyota could take risks there, as it had backups for each of those parts from earlier car models. At the same time, the chassis of the car was not changed at all, and was simply the same as for an earlier Camry model.

Deciding which version of a part to use is done using something called Trade-off Curves. These graph the trade-off between various variables for a component’s design, such as fuel-economy and engine price, or for a bicycle road resistance vs. wheel stability vs. tire suspension. This is a very data-driven approach where the component are actually made, in multiple versions, incrementally improved, and tested against predefined criteria. It’s enough to warm my Test Driven heart!

There are some conditions to making this work, of course. This quickly goes into Kennedy’s ideas of the Knowledge Based Organisation, which I’ll leave for a future post. It suffices here to state that next to ‘Set-based Concurrent Engineering’, he has ‘System Designer Entrepreneurial Leadership’, ‘Responsibility based Planning & Control’ and ‘Expert Engineering Workforce’ as pillars of knowledge based engineering.

Software

But how would we approach such a process when we’re dealing with software? Is it even necessary? Software is soft, malleable, and easily changed (Your code is, right?) so maybe it’s not necessary to work in such a way? I actually think it’s not only necessary, but it’s already being done, and at quite a large scale.

Linux distributions

The best examples I can think of that use this type of process for software development come from the Open Source world. The first one that comes to mind is the way Linux distributions are managed. A distribution such as Ubuntu is comprised of many different components (packages). My laptop for example, has 4566 packages installed, and there are many more available. These packages are not all created by the same people. They have different requirements for dependencies, different features, perhaps different alignments with feature-sets of other packages. And different levels of stability.

The people who assemble Ubuntu then have choices to make: Do we use Evolution as a mail client, or Thunderbird? Which version of Thunderbird? Do we need to make adaptations of Thunderbird to work seamlessly with our other packages? And they do. Some of those changes can be big, risky, but bring significant innovation (“Drop Gnome as the desktop environment and use Unity instead”), some are smaller and can more easily be reverted (“Use Empathy instead of Gaim as chat client, with both using the same underlying libraries to support different protocols”).

In a new release, most packages will be updated, but many changes are small, incremental and safe, while some are larger and bring more innovation. I doubt Mark Shuttleworth has a large set of trade-off curves on his desktop when the next version comes along, but he and the Ubuntu community are certainly making exactly those kind of trade-off choices.

Linux kernel

Another good example is again on the Linux front. The Linux kernel. This process may seem a little more complex, because it operates at a lower software level, but is in many aspects the same as above. In Linus, the kernel has its chief engineer (or ‘System Designer Entrepreneurial Leadership’). Calling the kernel developers an ‘Expert Engineering Workforce’ is also unlikely to trigger much discussion (though on the lkml, anything can trigger discussion). Though the kernel may seem less componentised than a distribution such as Ubuntu, it is in fact decoupled into many parts that can often be independently changed.

In the kernel, we again see set-based work in the way that separate components are sometimes incrementally developed, sometimes unchanged, and sometimes drastically changed or even replaced. Whether a change makes it into the kernel is the choice of Linus, but it is usually made based on discussion, numbers (“this filesystem structure has these performance characteristics, and such-and-such reliability” based on extensive testing of working code), and trust in team members. Only when a change is deemed safe and of high enough quality, it is pulled into the kernel. Then it is tested in integration with other changes before being handed to the outside world.

So we do already have set-based engineering in software. But how can you apply it to your own project, which might be large, or smaller? And what can be our software version of trade-off curves? Can we take advantage of the differences between hardware products and software to improve on this model.