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;
}
}
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;
}
}
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);
}
}
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);
}
}
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);
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();
}
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();
}
Thanks for reading. You can drop your comments, questions or suggestions.
Top comments (0)