Why do we need encapsulation?

If you have been dealing with OOP lately, you may have heard about encapsulation. Its the one of the principle mechanisms of object-oriented design, which restricts access to a class’s properties and allows you to manage a data flow. These are done with the use of access specifies: private, protected and public, which are supported in most programming languages.

  • Private data: can only be accessed by code in the same class;
  • Protected data: can only be accessed by code in the same class or in a derived class;
  • Public data: can be accessed by any code within the program;

You may use this table as a reference:

So, why do we even need to protect a class data?

The primary use of encapsulation is to keep our classes persistent and make sure they serve exactly that purpose, which they are assigned to do.

Let us look at the expample of the class, that manages a GPA of a student. The business requirement says, that the real GPA score is calculated by substracting penalty points from overall score.

class GPA {
	public $overall_score;
	public $penalty_points;

	public function __construct(float $overall_score, float $penalty_points)
	{
	     $this->overall_score = $overall_score;
	     $this->penalty_points = $penalty_points;
	}

	public function calculateGPA() : float
	{
	    return $this->overall_score - $penalty_score;
	}
}

The weak side of this class is, that it allows a user to avoid the given business logic and get the $overall_score property directly. You may say, that it is not difficult to understand the purpose of the class from the code, but imagine a class which is composed by a hundreds of lines. A single line function like calculateGPA() can easily be lost and users will be getting the wrong value.

To imporove the situation, we just need to change the access specifiers for the class properties to private

class GPA {
	private $overall_score;
	private $penalty_points;

	public function __construct(float $overall_score, float $penalty_points)
	{
	     $this->overall_score = $overall_score;
	     $this->penalty_points = $penalty_points;
	}

	public function calculateGPA() : float
	{
	    return $this->overall_score - $penalty_score;
	}
}

Now, a user will be forced to use calculateGPA() function, as accessing the class members directly will throw a fatal error.

Leave a Reply

Your email address will not be published. Required fields are marked *