Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Inheritance And Composition In A PHP Application

TwitterFacebookRedditLinkedInHacker News

As developers, we have encountered scenarios where some of the code we write can be reused by other code pieces. This has brought the concepts of code reuse in paradigms like object oriented programming. In this article, the author seeks to explain when to reuse code as well as how to achieve code reuse.

Relationships Between Classes

Reusing code from one class in another class tells, those classes have certain methods and properties that are common to each other. In this case reusing them will help to prevent code duplication. There are two ways a class can relate to another class and we will use the diagram below to aid our understanding between these two relationships.

Code Relationships

From the diagram above, we have a house, BathHouse which is a type of house and BathTub which is contained in a BathHouse. Considering these as separated classes, we can identify some relationships between them. A BathHouse is a specific type of a house which means BathHouse IS-A House, while BathHouse has a BathTub which is BathHouse Has-A BathTub. Using these concepts will help us understand when to implement various relationships in our codes. From here, we are going to take each relationship type, explain them a bit further and implement them with concrete examples.

IS-A Relationship

One way that a class can relate to the other is when the one is a type of the other. For instance when we take a car we can say it is a type of a vehicle. A teacher is also a type of staff. When one class is a type of the other, we say they have “IS-A” relationship.

Implementation of an IS-A Relationship with Inheritance

Inheritance is a design patter to implement a “IS-A” relationship between classes. Here, there is a parent-child relationship where a parent class with its own methods and properties and later a child class is created that can use the code from the parent class.

How to Achieve Inheritance

To achieve inheritance, we use the keyword extends. Let’s see it in practice:

// The parent’s class code
class House {
    protected $name;
    protected $size;
}

// The child can use the parent's class code
class BathHouse extends House { }

From the above code, House then become a parent class and the BathHouse which extends to the parent class is a child class.

HAS-A Relationship

Another important means to relate classes is when a class is part of another class. For instance, when we take a car class, it can be composed of an engine class as well as other components to achieve a holistic functioning car class.

Implementation of a HAS-A Relationship with Composition

Composition is a design patter to implement a “HAS-A” relationship between classes. Here, an instance variable is used to refer to other classes in its composed classed.

How to Achieve Composition

To achieve composition, one class is composed in other class as instance field. Let’s see it in practice:

class BathTub { }

class BathHouse {
    BathHTub tub;
}

Real World Implementation of Inheritance and Composition

We are going simulate using an MVC pattern to build a sample project. Here we will see how we can make use of these two concepts. With MVC app, when user requests to view a page by entering a URL. The Controller receives that request, uses the Models to retrieve all of the necessary data and organizes it, which then pass the data to the view to present the webpage to the user.

Working with a Base Controller

Usually the application has multiple controllers and to prevent multiple code duplicates, it is better to create a base controller from which other controllers can use to achieve various tasks. In this case, we can infer some relationship between the base controller and the controllers we will be creating. The controllers to be created will be of a type of the base controller so the inheritance can be used here, not composition.

class BaseController {

    public function loadView($view, $data=[]){
        if(file_exists($view .'.php')){
            require_once($view .'.php');
        } else {
            require_once('404.php');
        }
    }

    public function loadModel($model){
        require_once($model . '.php');
        return new $model(new Database());
    }

}

Here, we have two methods that our BaseController class performs; loading view and model. But in the loadModel method, we are passing a an instance of database class to the model so it can use it to perform the necessary operations on our our database.

Working with Models

Models are know to be a representation of real world object. Here, we a model an aspect of our database as a blog post, though a Blog database might have a lot of representations like users, etc. But we just need the Blog Posts, which we can say that our database has a blog post

<?php
class Blog {

    private Database $blogpost;

    public function __construct(Database $blogpost) {
        $this->blogpost = $blogpost
    }

    // Get All BlogPost
    public function getBlogs() {
        $this->blogpost->query("SELECT * FROM blog");
        return $this->blogpost->resultset();
    }

    // Get BlogPost By Id
    public function getPostById($id) {
        $this->blogpost->query("SELECT * FROM posts WHERE id = :id");
        $this->blogpost->bind(':id', $id);
        return  $this->blogpost->single();
    }

}

Working with a Specific Controller

Now that we have a base controller which can help us work with views and models as well as having a model to interact with our database, we are going to create a specific controller to help us read all blog posts.

class BlogsController extends BaseController {

    public function __construct() {
        // Load Models
        $this->blogModel = $this->loadModel('Blog');
    }

    // Load All Posts
    public function index() {
        $data = [
            'posts' => $this->blogModel->getBlogs()
        ];
        $this->loadView('blogs', $data);
    }

}

Here, we have created a controller the get all blog posts from our model and send that to the view. We can now present our view to the user.

Working with Views

<?php foreach($data['posts'] as $post): ?>
    <div class="card">
    <div><h2> ?php echo $post->title; ?> </h2></div>
    <hr/>
    <div><p> ?php echo $post->body; ?> </p></div>
<?php endforeach;?>

So the view just loop through the array data structure and render the content as cards to the user.

Comparing Inheritance and Composition

Now that we have clearer view of these two class relationship concepts, we can now compare both and find out where one outshines the other. Though both have their pros and cons but that isn’t the main concern of this article. Hence, we have to understand the best cases where we either implement class relationships with composition and inheritance. Use composition between two classes if one cannot exit without another. From our examples above, the Model class cannot exist without a Database class. If a class just want to make use of another class’ functionalities and properties then inheritance will be helpful. With our controllers, it obvious that BlogsController can exist completely without BaseController.

Conclusion

I hope you found this piece useful having being briefed some background on the meaning of inheritance and composition, also established how classes can be related using inheritance and composition.

Oliver Mensah

Oliver Mensah

Oliver is a recent computer science graduate who loves to share his knowledge through writing and speaking. He is a believer of a 'share and gain' principle to build his software engineering skills. As he waits to start his one-year mandatory national service after his graduation, he works as a freelancer, volunteering for Facebook Developer Circles Accra and actively helping other tech communities in Ghana through technical talks to build the tech ecosystem in Ghana.