Subscribe to PHP Freaks RSS

Poka Yoke – Saving Projects with Hyper-Defensive Programming

syndicated from www.sitepoint.com on June 28, 2017

When working in a medium to large team on the same codebase, it can sometimes become hard to understand each other's code and how to use it. Various solutions exist to help with this. For example, you can agree to follow a set of coding standards to make the code more readable for each other, or use a framework that's known to all (we've got a great Laravel intro premium course here).

However, this is often not enough, especially when someone has to dig back into a part of the application written some time ago to fix a bug or add a new feature. It can be quite hard to remember how particular classes were intended to work, both on their own and in combination with each other. At that point, it becomes easy to accidentally introduce side effects or bugs without realizing it.

A detected bug

These mistakes might get caught in quality assurance, but there's a realistic chance they might slip through. And even if they get caught, it can take a lot of time to send the code back and get it fixed.

So how can we prevent this? Enter "Poka Yoke".

What is Poka Yoke?

Poka Yoke is a Japanese term which roughly translates to "mistake-proofing". The term
originated in lean manufacturing, where it refers to any mechanism that helps a machine operator avoid mistakes.

Outside of manufacturing, Poka Yoke is also often used in consumer electronics. Take, for example, a SIM card, which can only fit one way a sim tray because of its asymmetrical shape.

A SIM card and tray, illustrating how the SIM card can only fit one way.

An example of hardware lacking in Poka Yoke is the PS/2 port, which has exactly the same shape for a keyboard connector and a mouse connector. They can only be differentiated by using color codes, so it is easy to accidentally switch the connectors and insert them in the wrong ports because they both fit the same way.

PS/2 ports for keyboards and mice, illustrating how they use an interchangeable format making it too easy to accidentally insert one into the other.

Besides being used in hardware, the concepts of Poka Yoke can also be applied to programming. The idea is to make the public interfaces of our code as easy as possible to understand, and to raise errors as soon as our code is being used incorrectly. This might seem obvious, but in reality we often come across code that is lacking in these regards.

Note however, that Poka Yoke is not meant to prevent intentional abuse. The goal is only to prevent accidental mistakes, not to secure your code against malicious usage. As long as someone has access to your code, they will always be able to get around your safeguards if they really want to.

Before discussing what specific measures you can take to make your code more mistake-proof, it is important to know that Poka Yoke mechanisms can generally be divided into two categories:

  • Mistake prevention
  • Mistake detection

Mistake prevention techniques are helpful for catching mistakes early on. They are meant to make sure no one can accidentally use our code incorrectly, by making the interfaces and behavior as straightforward as possible. Think of the example of the SIM card, which can only fit one way in a SIM tray.

Mistake detection mechanisms, on the other hand, live outside of our code. They monitor our applications to watch for potential mistakes and warn us about them. An example can be software that detects whether a device connected to a PS/2 port is of the correct type, and if not show a warning to the user clarifying why it doesn't work. This particular software could not prevent a mistake, because the connectors are interchangeable when plugging them in, but it can detect one and warn us about it so the mistake can be fixed.

In the rest of this article we will explore several methods we can use to implement both mistake prevention and mistake detection in our applications. But keep in mind that this list is just a starting point. Depending on your specific application, additional measures might be possible to make your code more mistake-proof. Also, it's important to keep the upfront cost of Poka Yoke in mind and make sure it's worth it for your specific project. Depending on the complexity and size of your application, some measures may be too costly compared to the potential cost of mistakes. So it is up to you and your team to decide which measures are best for you to take.

Mistake prevention examples

A targeted virus, molecular scale view CG render

(Scalar) type declarations

Previously known as type hints in PHP 5, type declarations are an easy way to start mistake-proofing your function and method signatures in PHP 7.

By assigning specific types to your function arguments, it becomes harder to mix up the order of arguments when calling the function.

For example, let's take this Notification that we might want to send to a user:

<?php

class Notification { private $userId; private $subject; private $message;

public function __construct( $userId, $subject, $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; }

public function getUserId() { return $this->userId; }

public function getSubject() { return $this->subject; }

public function getMessage() { return $this->message; } }

Without type declarations, we can easily inject the incorrect types of variables which would probably break our application. For example, we could assume that the $userId should be a string, while it might actually have to be an int.

If we injected the wrong type, the error would probably go undetected until the application tries to actually do something with the Notification. By then, we'd probably get some cryptic error message about an unexpected type, but nothing that immediately points to our code where we inject a string instead of an int.

Because of this, it is often more interesting to force the application to crash as soon as possible, so that bugs like these get caught early on during development.

In this case, we could simply add some type declarations and PHP will stop and warn us immediately with a fatal error when we mix up the types of our arguments:

<?php

declare(strict_types=1);

class Notification { private $userId; private $subject; private $message;

public function __construct( int $userId, string $subject, string $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; }

public function getUserId() : int { return $this->userId; }

public function getSubject() : string { return $this->subject; }

public function getMessage() : string { return $this->message; } }

Note however that, by default, PHP will try to coerce incorrect arguments to their expected types. To prevent this, it is important that we enable strict_types so we actually get a fatal error when a mistake is made. Because of this, scalar type declarations are not an ideal form of Poka Yoke, but they're a good start to reducing mistakes. Even with strict_types disabled, they can still serve as an indication of what type is expected for an argument.

Continue reading %Poka Yoke – Saving Projects with Hyper-Defensive Programming%