Saturday 29 May 2021

Php: Implement singleton design pattern

Singleton pattern restricts the instantiation of a class to one object. That is you can't create more than one object to this class. This is useful when exactly one object is needed to coordinate actions across the system.

 

Example

Database connection object is single across your application.

 

How to design a singleton class?

 

a.   Make __construct method private

b.   Make __clone method private

c.    Make __wakeup method private

d.   Create get_instance method, which return existing object, if it is already exist, else create new one.

 

Find the below working application.

 

singleton_class_demo_1.php

#!/usr/bin/php

<?php
    class MyClass{
        public static $instance;

        public static function get_instance(){
            if(null == static::$instance){
                static::$instance = new static();
            }
            return static::$instance;
        }

        // Prevent creation of object using constructor
        private function __construct(){

        }

        // Prevent cloning of object
        private function __clone(){

        }

        // Prevent unserializing of singleton
        private function __wakeup(){

        }

        public function about_me(){
            echo "\nI am MyClass instance\n";
        }
    }

    $my_instance_1 = MyClass::get_instance();
    $my_instance_2 = MyClass::get_instance();

    var_dump($my_instance_1 === $my_instance_2);

    $my_instance_1->about_me();
    $my_instance_2->about_me();

    // Since constructor is private, below statement throws an error.
    //$my_instance_3 = new MyClass();

    // Since clone method is private, following statement throws an error.
    //$my_instance_4 = clone $my_instance_2;
    
?>

 

Output

$./singleton_class_demo_1.php 

bool(true)

 

How can I make sure that all the subclasses also singleton?

a.   Define __construct method using protected access specifier

b.   Define __clone method using private access specifier

c.    Define __wakeup method using private access specifier

d.   Define a static protected variable to hold the instance of class, and define get_instance method that return existing object, else it create one.

e.   Define new class that extend the existing singleton and redeclare the static variable in child class again.

 

Find the below working application.

 

singleton_class_demo_2.php

#!/usr/bin/php

<?php
    class MyClass{
        protected static $instance;

        public static function get_instance(){
            if(null === static::$instance){
                static::$instance = new static();
            }
            return static::$instance;
        }

        // Prevent creation of object using constructor
        protected function __construct(){

        }

        // Prevent cloning of object
        private function __clone(){

        }

        // Prevent unserializing of singleton
        private function __wakeup(){

        }

        public function about_me(){
            echo "\nI am MyClass instance\n";
        }
    }

    class MySubClass extends MyClass{
        protected static $instance;

        public function about_me(){
            echo "\nI am MySubClass instance\n";
        }
    }

    $my_instance_1 = MyClass::get_instance();
    $my_instance_2 = MyClass::get_instance();

    $my_instance_1->about_me();
    var_dump($my_instance_1 === $my_instance_2);

    $my_instance_3 = MySubClass::get_instance();
    $my_instance_4 = MySubClass::get_instance();

    $my_instance_3->about_me();

    var_dump($my_instance_3 === $my_instance_4);

    // Since constructor is private, below statement throws an error.
    //$my_instance_3 = new MySubClass();

    // Since clone method is private, following statement throws an error.
    //$my_instance_4 = clone $my_instance_2;
    
?>

 

Output

$./singleton_class_demo_2.php 


I am MyClass instance
bool(true)

I am MySubClass instance
bool(true)

 

 

 

 

 

 

 

 

Previous                                                    Next                                                    Home

No comments:

Post a Comment