SOLID principles PHP Edition. Today, Open/Closed Principle

Jose Cerrejon
3 min readApr 18, 2024

--

Open/Closed Principle. Generated with AI.

First of all, here you have the four principles of SOLID:

Single Responsibility Principle: A class should have only one reason to change.
Open/Closed Principle: A class should be open for extension but closed for modification.
Liskov Substitution Principle: You should be able to use any subclass in place of its parent class.
Interface Segregation Principle: A class should not be forced to implement an interface it doesn’t use.
Dependency Inversion Principle: High-level modules should not depend on low-level modules. Both should depend on abstractions.

The Open/Closed principle states that “software entities (classes, modules, functions, etc.) must be open for extension, but closed for modification”. So, once a software entity is developed and tested, it should be possible to extend its behavior without having to modify its source code.

Look at the following code:

class Rectangle {
public $width;
public $height;

public function __construct($width, $height) {
$this->width = $width;
$this->height = $height;
}
}

class Circle {
public $radius;

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

class AreaCalculator {
public function calculate($shapes) {
$area = [];
foreach ($shapes as $shape) {
if ($shape instanceof Rectangle) {
$area[] = $shape->width * $shape->height;
} elseif ($shape instanceof Circle) {
$area[] = $shape->radius * $shape->radius * pi();
}
}

return array_sum($area);
}
}

In this example, if you wanted to add a new form, you would have to modify the AreaCalculator class and add a new condition in the calculate method. In other words, Open/Closed principle says that you should be able to add new functionality to a class without modifying it.

The example above violates the Open/Closed principle.

A better way to do this would be to define an area method in each form and then call that method in AreaCalculator:

interface Shape {
public function area();
}

class Rectangle implements Shape {
public $width;
public $height;

public function __construct($width, $height) {
$this->width = $width;
$this->height = $height;
}

public function area() {
return $this->width * $this->height;
}
}

class Circle implements Shape {
public $radius;

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

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

class AreaCalculator {
public function calculate($shapes) {
$area = [];
foreach ($shapes as $shape) {
$area[] = $shape->area();
}

return array_sum($area);
}
}

Now, if you wanted to add a new form, you would just have to create a new class that implements the Shape interface and defines the area method. The AreaCalculator class would not have to be modified to accommodate the new form. Therefore, it would comply with the Open/Closed principle.

This article was published for the first time on the blog misapuntesde.com, where you can read news/tutorials about Raspberry Pi & Linux, and soon about Mac, DevOps, development, and all the things you and I want to learn.

I’m looking for a job, so visit my LinkedIn profile here! Thank you!

--

--