Michael Samuel
Michael Samuel

Reputation: 3920

The actual real life use of PHP OOP interface

I'm new to OOP and learning about polymorphism using interfaces. There is a popular polymorphous example which is calculating area depending on shape.

The code:

<?php

interface Shape {
          public function calcArea();
}

class Circle implements Shape {
      private $radius;

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

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

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

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

      public function calcArea() {
             return $this -> width * $this -> height;
      }
}
$circ = new Circle(3);
$rect = new Rectangle(3,4);

echo $circ -> calcArea();
echo '<br />';
echo $rect -> calcArea();

?>

This is the same code without using interface at all:

<?php

class Circle {
      private $radius;

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

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

class Rectangle  {
      private $width;
      private $height;

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

      public function calcArea() {
             return $this -> width * $this -> height;
      }
}
$circ = new Circle(3);
$rect = new Rectangle(3,4);

echo $circ -> calcArea();
echo '<br />';
echo $rect -> calcArea();

?>

Both work as expected but the interface has actually no use! Until now OOP seems just to add more layers of unnecessary complexity. Like instead of switch or if conditions, we use classes and a common interface. I find it actually more easy on the eye to just use the IF or switch conditions (as long as you don't keep repeating the same code) after each other instead of each one in a separate class.

The only benefit to OOP in general seems to be when designing an API. So the end user of the API can actually access the method needed directly without having to call a lot of unneeded code.

From developers side though, any modification you apply to a certain class may actually need to be done to other part of the code as well. Moreover, a developer anyway will have to take a look at other part of the code to be able understand how it works. Further more, inline PHP in HTML will be there so any modification of a certain method may need changes in the instances of the objects declared.

Am I missing something?

Upvotes: 3

Views: 3233

Answers (2)

Omer Farooq
Omer Farooq

Reputation: 4084

This is a great question and i have seen people asking it over and over again. So i will try to simplify it for you, (interface part comes in the end).

First of all you dont necessarily have to use OOP everywhere, most of the wordpress core code is written in procedural php (not sure about the current builds), and its not a bad thing. Most of the times it does simplify things for new programmers, and thats the whole point of using OOP i.e to add abstraction over abstraction, so when the programmer is working on a specific functionality he doesn't have to worry about the other aspects. So for instance if i wanted to store an image from a registration form, I would have 2 classes. One for Users and one for image. So here is how it would look like.

/*********** User Class ***********/

        Class User
        {
          public function storeUser($request, Image $image)
          {
             // Fetch Image from the form request and pass it to the

             $image = $request->input('image');
             $image->uploadImage($image, $imagePath);

             // Now upload other user attributes
          }
        }

/ ********* Image Class **********/

        Class Image
        {
          public function uploadImage($image, $imagePath){
             // Code to UploadImage
          }
        }

I usually have a class called users and a method called storeUser in it, where i would add the users to the database. Now i would also have another Class called Image with a method called uploadImage.

You could have done the same thing with a function which is also fine, but what if you want another feature lets say when a user updates his profile, delete the old image and upload a new one. For this you would have to include another function, which would have all the code of uploadimage and some other code to delete the previous image.

But now you are repeating yourself, and avoiding DRY Principle (Do not repeat yourself). But lets say you have another function for deleteUserImage which would delete the image and then in turn call the upload function.

So if this is what you were thinking about doing, you were actually using OOP subconsciously, but in a very messy way, because a class is just a collection of functions and variables. But you are lacking many other functionality like scopes, static, some other cool stuff and my favourite $this :)

The Number of abstractions that you add can depend on your deadlines, future scalability etc. You dont have to absolutely go crazy with abstractions, but a simple rule of thumb is the more abstractions you have the more manageable and flexible your code is.

Lets say for an argument that you have created your app in php and mysql and launched it, But the app became much popular then you anticipated. And suddenly you have millions of users, but your mysql server is somehow not supporting this huge number of users and you want to shift to another database like postgres or cassandra but all your mysql queries are mixed up with the php code, and there is no painless way of achieving this but to create everything from scratch. This is a common problem that many huge organizations had experinced including twitter and facebook. But if you created your app with abstractions, where all your queries go in one class, your controllers go in another. All you would have to do is just modify the driver and queries in a few files and you will start using another database all together.

Now lets come back to the original question about interface. You might think interfaces are just a waste of time because it is simply a list of all the methods that you are going to implement in the class, Right? Well atleast it seemed to me when i started OOP. But it turns out that i was stupid, because at the time, i didn't knew about the SOLID Principles.

SOLID is actually an abbreviation of 5 of the best principles ever written for programming, and they support each other very well. "O" in the SOLID stands for "Open and Closed Principle", and what it means is that the method is Closed for changes but Open for Extensions. In simple words what that means is that once you have a basic working app, you should never modify the existing method parameters that you have in your interface because if other files are also using that class it would break them. And the way you add restriction to is through interfaces. So how do you add a new feature without modifying the method? well you dont directly modify a method, you extend it.

Upvotes: 1

Mischback
Mischback

Reputation: 851

I think this question would be better suited on Programmers SE.

Anyway: Your minimal example is - minimal. Yes, in that case using the interface would be considered overkill, but there are many usecases, where implementing/specifying interfaces do make sense.

If you're developing open source, you may want to specify an interface, even if you're the only developer at that moment, just to make sure, that future contributers will easily get access to your code and can provide their own extensions/additions to your project.

But even in your minimal example, there is some usecase: Imagine an application where some part of the app deals with Shape objects in general. Imagine, it doesn't matter, which actual shape there is to deal with.

With using the interface, you are forced to implement the method for all derived classes. This allows scalability and maintainability.

Also, see this SO post on the same subject.

Upvotes: 2

Related Questions