Mary Poppendieck tells this great story about when the manufacturing plant she worked for transitioned to Lean. When they started, she says, they had this separate QA group whose job it was to find defects in the products after they were already made (sound familiar?). But then they took these QA folks and moved them out onto the production line to figure out how to make stuff without defects in the first place. Huh! Wouldn’t it be cool if we could do that for software?
This is the idea behind Poka-Yoke, or mistake proofing. It means setting things up in such a way that prevents people from making mistakes.
You’ve probably seen this before in product design – monitor cables with male & female ends that prevent us from plugging them in the wrong way. Or in software with controls like dropdown lists (male, female) that prevent users from entering incorrect values (I’ll let you use your imagination).
Toyota brings this idea onto their production lines with devices that prevent incompatible parts from fitting together. But also with poka-yoke methods that detect problems and shut down the machine (stop the line) or activate alarms so people are immediately alerted to correct it. So even when it’s not possible to completely prevent errors from occurring, they still prevent those errors from entering production. And they can then fix those errors immediately before they get a chance to compound into serious problems.
So How Do We Poka-Yoke our Code?
Compilers. If we’re using a compiled language then our compiler prevents language-specific errors from entering the software –- it won’t even build the software if it detects errors, right? So we can start by designing our code in a way that actively pushes things up from run-time detection to compile time detection. Using thing like using generics and favoring objects over primitives. And avoiding hacks like hiding things in String or Object types that might feel flexible but that allow errors to sneak right past our first poka-yoke.
Modern Languages. We can build on this idea by using modern languages that are specifically designed to prevent common programming errors. Things like functional languages that use immutable values and methods with no side effects that make our code safer by preventing us from making those mistakes in the first place.
And if we’re stuck with older languages, we can still learn about the newer languages & incorporate some of their ideas into our own code to make it less error-prone. Stephan Schmidt (@CodeMonkeyism) wrote an excellent post on this Go Ahead: Next Generation Java Programming Style that I highly recommend.
Automated Tests. Well, this is all lovely, but of course it won’t find even the most basic of application errors. So, like Toyota, we need to supplement our builds with poka-yoke methods that detect problems and alert us to correct them. We’re probably already using automated tests to validate our application logic –- issues our compiler can’t catch. So what we can do are employ our own poka-yoke techniques to give us better coverage and that truly “stop the line” to prevent errors from moving forward. Things like:
- Using TDD & ATDD to ensure we don’t write a line of production code without test coverage to poka-yoke it.
- Continuous integration boxes that alarm when these tests fail so we’re immediately alerted to fix them.
- Tools & scripting languages that automatically run the appropriate test suites on check ins and deployments and to prevent (or at least alarm) us from taking those actions upon failure.
Exploratory Testers. Okay, but what about all the stuff we don’t think to put in our tests (it breaks when you do what?!). This is where we need to take our Testers (aka “QA Folks”) and move them out onto the production line (yep, right there in our programming spaces!) to figure out how we can make stuff without defects in the first place.
I know, we’re really super smart and all, but software development is hard. And if we knew how to make software without defects in the first place, well… then you probably wouldn’t have read this far down in this post by now (and if you did, feel free to share your secret with the rest of us in the comments).
We are really good at building software. But we need another perspective. While we’re focused on how to make things work, it’s helpful to have people focused on how things might break so that we can then feed that knowledge into what we’re building to prevent those
defects from happening in t
he first place. This means things like pairing programmers & testers on each story so we’ve got that tester right there on our coding floor with us doing exploratory testing early & often. And it means feeding their results into new automated tests that then become part of our poka-yoke.
Even at Toyota they can’t know from day 1 all the things that might break. Instead, they employ processes that are continually inspecting for problems in the system and, when one is found, they take steps like adding new poka-yoke methods to prevent it from ever occurring again. Wouldn’t it be neat in software if we found a way to stop repeating our same mistakes over again? :-)
I have obviously only barely scratched the surface here, so am hoping this post will generate more ideas. What ways can you see for poka-yoking your code? How can we evolve these ideas to really make them work?