
The first time I was using PHP Mess Detector (a PHP Quality Tool), I was very surprised. Because, when I type an Else expression, it raises an error which it said: “An if expression with an else branch is never necessary”. What the f***, I have never seen something like this before.
Indeed, this principle came from Jeff BAY in Object Calisthenics, an exercise-chapter from The ThoughWorks Anthology (written by many well-known programmers like Martin FOWLER). In this chapter, Jeff BAY defined 9 rules for writing better software. “Avoid else expression” is one of them.
Let’s see how we can write code without the traditional “else”.
Solution 1: reorder your code
Ok, given you have a function like this:
<?phpfunction getUserDenomination(User $aUser){ if ($aUser->getFirstName() && $aUser->getLastName()) { $name = $aUser->getFirstName() ." ". $aUser->getLastName(); } else { $name = "Unknown user."; }
return $name;}
The first step, is to replace $name
variable by a return
statement.
<?phpfunction getUserDenomination(User $aUser){ if ($aUser->getFirstName() && $aUser->getLastName()) { return $aUser->getFirstName() ." ". $aUser->getLastName(); } else { return "Unknown user."; }}
And because, we’re not beasts, we should inverse condition (avoid finish your function with pseudo-exceptions).
<?phpfunction getUserDenomination(User $aUser){ if (!$aUser->getFirstName() && !$aUser->getLastName()) { return "Unknown user."; // <-- early return }
return $aUser->getFirstName() ." ". $aUser->getLastName();}
And tadaaaa! else
condition disappears!
Ok, you’re kind but this example is very easy. Trust me, I write specific code and I can’t drop else! — one of my colleague
That was my colleague’s answer when I mentioned this. But you know, every developer writes specific
code (in 2016, CRUD were generated). If you don’t, I’m sorry for you!
So, sometimes it’s difficult to avoid this expression. Most of the time, it came from another
problem: design patterns misknowledge.
Solution 2: State Pattern
If your code look like this:
<?php// I want to move my carif ($car->isStarted()) { $car->move();} elseif ($car->isStopped()) { throw new Exception("Start car first!");} elseif ($car->is moving()) { // do nothing}
First of all, replace these conditions with a switch
statement. It’s pretty much the same, but a
little bit more readable.
And then, you should use the State Pattern.
<?php
class Car{ // ... private $state;
function __construct(CarStateInterface $state) { $this->setState($state); }
private function setState(CarStateInterface $state) { $this->state = $state; }}
interface CarStateInterface{ public function start(); public function move(); public function stop();}
abstract class AbstractCarState implements CarStateInterface{ public function start() { throw new \Exception("Illegal state transition"); } public function move() { throw new \Exception("Illegal state transition"); } public function stop() { throw new \Exception("Illegal state transition"); }}
//// 1 Class per State//
class MoveCarState extends AbstractCarState{ /** @return StopCarState */ public function stop() { return new StopCarState; }
/** @return MoveCarState */ public function move() { return $this; }}class StopCarState extends AbstractCarState{ /** @return StartCarState */ public function start() { return new StartCarState; }}class StartCarState extends AbstractCarState{ /** @return StopCarState */ public function stop() { return new StopCarState; }
/** @return MoveCarState */ public function move() { return new MoveCarState; }}
Now I can move my car like this, without switch/else/elseif condition!
<?php$myTestcar = new Car(new >WhateverCarState());$myTestcar->move();
Nb: Instead of creating an AbstractCarState, you can implement the CarStateInterface for all of your XXXCarState.
Solution 3: Strategy Pattern
Sometimes, you have to check the object’s instance before doing something.
<?phpif ($mybeer->type == "noAlcoholBeer") { $mybeer->drinkNoAlcoholBeer();} elseif ($mybeer->type == "strongBeer") { $mybeer->drinkStrongBeer();} else { $mybeer->drinkSoftBeer();}
<?phpinterface DrinkBehaviorInterface{ public function drink();}//1 class per behaviorclass DrinkNoAlcoholBeer implements DrinkBehaviorInterface{ /** @return string */ public function drink() { return "Oh it's shitty!"; }}class DrinkSoftBeer implements DrinkBehaviorInterface{ /** @return string */ public function drink() { return "I feel dehydrated and I'm Ok!"; }}
class DrinkStrongBeer implements DrinkBehaviorInterface{ /** @return string */ public function drink() { return "Damn, I can't drive!"; }}class Beer{ /** @var DrinkBehaviorInterface */ private $iBeerBehavior;
function __construct(DrinkBehaviorInterface $beerBehaviorType) { $this->setBeerBehavior(); }
public function applyDrink() { return $this->iBeerBehavior->drink(); }
public function setBeerBehavior(DrinkBehaviorInterface $beerBehaviorType) { $this->iBeerBehavior = $beerBehaviorType; }}
Now you can use it like this:
<?php$kwak = new Beer(new DrinkStrongBeer());echo $kwak->applyDrink(); //Damn, I can't drive!
Solution 4: NullObject Pattern
In this solution, examples come from
Dominik Liebler Github repository
Sometimes need to check if an object isn’t null before doing something. Like that:
<?phpif (!is_null($logger)) { $logger->log("banana");}
This is how NullObject Pattern works:
<?php
interface LoggerInterface{ public function log($str);}class PrintLogger implements LoggerInterface{ public function log($str) { echo $str; }}class NullLogger implements LoggerInterface{ public function log($str) { // do nothing }}
class Service{ public function __construct(LoggerInterface $log) { $this->logger = $log; }
public function doSomething() { // no more check "if (!is_null($this->logger))..." with the NullObject pattern $this->logger->log("Oh, I'm doing something!"); // something to do... }}
This is how it works:
<?php$service = new Service(new NullLogger());$service->doSomething(); //(no output)
$service = new Service(new PrintLogger());$service->doSomething(); //Oh, I'm doing something!
As far as I’m concerned, I prefer this pattern when he’s combined with patterns like Factory.
Conclusion
I apply this principle every day. And now 90% of my if blocks, does not contain any else expression! (yeah, I am lazy sometimes ;-)). Most of the time, the first solution is the solution. Take care, sometimes too many design patterns lead your application to over-engineering. First, make sure it’s relevant and remember: pragmatism over theory.
Oh, by the way, I implement these patterns in a Github repository. You can take a look, it’s fully tested!
About the author

Hey, I'm Maxence Poutord, a passionate software engineer. In my day-to-day job, I'm working as a senior front-end engineer at Orderfox. When I'm not working, you can find me travelling the world or cooking.
Follow me on Bluesky