DEV Community

Cover image for SOLID: Fundamental Principles of Software Development using PHP (2)
Elvis
Elvis

Posted on

SOLID: Fundamental Principles of Software Development using PHP (2)

This is a continuation of our implementation of SOLID principles using PHP. I encourage you to go through the first part where we implemented the first principle, Single-Responsibility Principle.

In this episode we shall implement the second principle, Open and Closed Principle. At the end of the whole series, we shall be writing real application with clean. Please read it to the end, drop your questions incase if there is any part that needs clarity. Also don’t forget to share. Thank you.

SOLID stands for:

S — Single-Responsibility Principle

O — Open-Closed Principle

L — Liskov Substitution Principle

I — Interface Segregation Principle

D — Dependency Inversion Principle

The Open-Closed principle states that Objects or entities should be open for extension but closed for modification.

In the first part, we created an app that collects shapes, calculate their areas and returns their sum. Assuming, we have other shapes, we will have to modify the areasumcalculator class, which is against the principle.

Our aim here is to ensure that a class or an entity can extended but not modified.

To achieve this, we create an interface that all shapes must follow.

` interface ShapeArea{
public function area();

}`

` // exception, incase a shape that does not implements our interface is provided.
class InvalideShapeException extends Exception
{
public $message;

function __construct($mess = 'Invalid shape')
{
$this->message = $mess;
//return 'This shape is invalid';
}

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

We will create shape classes that will implement the interface

class Square implements ShapeArea
{
    public $length;

     function __construct($length)
    {
      $this->length = $length;
    }

    public function area()
    {
      $area = $this->length * $this->length;
      return $area;
    }

}

class Circle implements ShapeArea{
    public $radius;

     function __construct($radius)
    {
        $this->radius = $radius;
    }
    public function area()
    {
      $area = pi() * ($this->radius * $this->radius);
       return $area;
    }
}

Enter fullscreen mode Exit fullscreen mode

To test our exception, lets create another shape that doesn't implement shapesurface

class Triangle{
  public $breadth;
  public $height;

  function __construct($breadth,$height)
  {
$this->breadth = $breadth;
$this->height = $height;
  }
   public function myArea()
   {
      $area = 1/2 * ($this->breadth * $this->height);

      return $area;
   }

}
Enter fullscreen mode Exit fullscreen mode

Now lets go back to our areasumcalculator class

class AreaSumCalculator{
    protected $shapes;

     public function __construct($shapes = [])
     {

       $this->shapes = $shapes;
     } 

    public function sum()
    {
        $area = [];
      foreach($this->shapes as $shape)
      {
        if(is_a($shape, 'ShapeArea'))
        {
          $area[] = $shape->area();  
        }
        else{
          throw new InvalideShapeException;
        }



      }
      return array_sum($area);
    }

}

Enter fullscreen mode Exit fullscreen mode

Then the class to class to output the calculated sum

class AreaSumCalculatorOutput{
    public $areasumcalculator;

   public function __construct(AreaSumCalculator $areasumcalculator)
    {
        $this->areasumcalculator = $areasumcalculator;
    }

    public function jsonOutput()
    {
      $data = [
        'sum' => $this->areasumcalculator->sum(),
      ];

      return json_encode($data);
    }
}
Enter fullscreen mode Exit fullscreen mode

Lets create shapes or objects (instance of classes)

$circle = new Circle(10);
$square = new Square(5);

$triangle1 = new Triangle(10,23);
$triangle = new Triangle(1,23);
Enter fullscreen mode Exit fullscreen mode

Create a shape variable to accept an array of the area of shapes (object created)

$shapes1 = [$circle, $square];
$shapes2 = [$triangle1, $triangle];

Lets test our first shapes (circle and square), it implements the interface.

/ calculate the sum of the areas of the shapes

try{

  $area_sum_calculator = new AreaSumCalculator($shapes1); 

  // answer :
/* {
  "sum": 339.1592653589793
}
*/


  // output the sum
$area_sum_output = new AreaSumCalculatorOutput($area_sum_calculator);

// call the output

$json_output = $area_sum_output->jsonOutput();

echo $json_output .'<br>'; 

}catch(InvalideShapeException $e)
{
  echo "Caught my exception: \n ";
  echo $e->getMyMessage();

}

Enter fullscreen mode Exit fullscreen mode

Test the second shape

try{

  $area_sum_calculator = new AreaSumCalculator($shapes2); 

  // answer :
// Caught my exception Invalid shape


  // output the sum
$area_sum_output = new AreaSumCalculatorOutput($area_sum_calculator);

// call the output

$json_output = $area_sum_output->jsonOutput();

//echo $json_output;

}catch(InvalideShapeException $e)
{
  echo "Caught my exception\n";
  echo $e->getMyMessage();

}

Enter fullscreen mode Exit fullscreen mode

Thanks for reading. You can drop your comments, questions or suggestions.

Top comments (0)