in php object oriented programming oop design pattern refactor ~ read.

Refactoring Conditional Expressions

In this post we are going to talk about how to refactor your Conditional Expressions in PHP.

What is Conditional Expressions?

Just like the above diagram that Conditional Expressions performs different computations or actions depending on whether a programmer-specified boolean condition evaluates to true or false.

<?php  
$a = 1;
$b = 2;

/* If condition is true then assign a to result otheriwse b */
$result = ($a > $b ) ? $a :$b;

echo "TEST1 : Value of result is $result<br/>";

/* If condition is true then assign a to result otheriwse b */
$result = ($a < $b ) ? $a :$b;

echo "TEST2 : Value of result is $result<br/>";  

Refactor Conditional Expressions

In the following we are going to have a look at 4 conditional expressions and refactor them.

Example 1 Before

<?php

public function calCost(Project $project, $time, $type) {

    if($type == 'complex' || $time == 'rush') {
        $cost = ($project->getBaseRate() * $project->getSize()) * 1.5;
    } else {
        $cost = $project->getBaseRate() * $project->getSize();
    }

    return $cost;
}

As you can see, the above code is pretty common among our programmers and it is looking pretty straightforward for us. How can we refactor it to make it more readable to us?

Example 1 After

<?php  
public function calCost(Project $project, $time, $type)  
{
    if( $this->isNotSimple($urgency, $type) ) {
        $cost = $this->calculateComplexRate($project);
    } else {
        $cost = $this->calculateDefaultRate($project);
    }

    return $cost;
}

private function isNotSimple($time, $type)  
{
    return $type == 'complex' || $time == 'rush';
}

private function calComplexRate($project)  
{
    return ($project->getBaseRate() * $project->getSize()) * 1.5;
}

private function calDefaultRate($project)  
{
    return $project->getBaseRate() * $project->getSize();
}

In the above code, we break down the condition into methods. In this case we don't have to bother look at the following code, after we finish the first method we can pretty much gain a good understanding of the functionality of calCost() method.

Example 2 Before

This example is also rather common for programmers.

<?php  
public function calProjectRate($request, $language, $timeline)  
{
    if ($request == 'free') {
        return false;
    }
    if ($language == 'Fortran 1') {
        return false;
    }
    if ($timeline == '1 second') {
        return false;
    }
    // continue rate processing
}

It is looking pretty normal, we return first as long as there is one condition that doesn't match. But let's look at how can we refactor it into a better version.

Example 2 After

<?php

public function calProjectRate($request, $language, $timeline)  
{
    if($this->isOurWork($request, $language, $timeline)) {
        return false;
    }
    // continue rate processing
}

private function isOurWork($request, $language, $timeline)  
{
    return $request == 'free' || $language == 'Fortran 1' || $timeline == '1 second';
}

Example 3 Before

<?php  
public function calProjectRate()  
{
    if ($this->isComplexWork()) {
        $rate = $this->calculateComplexRate();
        $this->verifyRateWithTheBoss($rate);
    } else {
        $rate = $this->calculateBaseRate();
        $this->verifyRateWithTheBoss($rate);
    }
}

The above code looks pretty normal and logical at the first time. But let's see if we can make it better cause there is some duplications here.

Example 3 After

<?php  
public function calProjectRate()  
{
    if ($this->isComplexWork()) {
        $rate = $this->calculateComplexRate();
    } else {
        $rate = $this->calculateBaseRate();
    }

    return $this->verifyRateWithTheBoss($rate);
}

Or we can use ternary operator to simplify it further.

<?php  
public function calProjectRate()  
{
    $rate = $this->isComplexWork()
            ? $this->calculateComplexRate()
            : $this->calculateBaseRate();

    return $this->verifyRateWithTheBoss($rate);
}

Example 4 Before

<?php  
public function filterWorkRequests()  
{
    if ($this->workIsImpossiable()) {
        $response = $this->absolutelyNot();
    } else {
        if ($this->workIsHard()) {
            $response = $this->possibly();
        } else {
            $response = $this->weWouldLoveTo();
        }
    }

    return $response;
}

This kind of condition is pretty common no matters what language we use. We can always encounter this situation somewhere sometime. Let's see how can we make it better.

Example 4 After

<?php

public function filterWorkRequests()  
{
    if ($this->workIsImpossiable()) {
        return $this->absolutelyNot();
    }

    if ($this->workIsHard()) {
        return $this->possibly();
    }

    return $this->weWouldLoveTo();
}

In the refactored version we are using a guard clause to exit the method as soon as we deem the work inappropriate. We know already we don't want it, so there's no sense in continuing the method.

End

As always if you have any comments or ideas please leave a comment below. Thanks!

comments powered by Disqus