3

While learning about design patterns I have come across the singleton pattern:

class Singleton
{
    private static $instance = null;

    private function __construct()
    {
    }

    public static function getInstance()
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }

        return self::$instance;
    }
}

I'm having a hard time understanding what the constructor does in this circumstance. There isn't any code being executed between the braces? How does this work? Thanks.

tereško
  • 58,060
  • 25
  • 98
  • 150
jstyles85
  • 61
  • 4
  • @Akintunde I don't think he's asking how the construct works. – Chin Leung Sep 26 '17 at 17:36
  • FYI, singleton is actually an anti-pattern, that is used to create global state. The only practical use of this patter is as first step in refactoring a codebase, where you want to move from included-oriented programming to object-oriented programming. A proper OOP code does not contain this anti-pattern. – tereško Sep 26 '17 at 18:59

2 Answers2

6

The constructor marked private is used to avoid the instantiation of the singleton class, so there is always only a single one.

For example we cannot do this:

$singleton = new Singleton();

It yields:

Fatal error: Call to private Singleton::__construct() from invalid context

You must fetch the singleton:

$singleton = Singleton::getInstance();
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • thanks, it makes much more sense to me now. Is this considered a valid use of the construct function or is this viewed as somewhat of a "hack" since there isn't anything actually being constructed? – jstyles85 Sep 26 '17 at 17:48
  • It's a valid use of constructor, because we can make some initialization in it, it's also a hach to restrict the number of instances that are being create to a single instance that is shared. Sorry for my bad english. – Mame Medoune Diop Sep 26 '17 at 18:03
  • Thanks for making that clear. Your english seems fine! – jstyles85 Sep 26 '17 at 18:10
0

As the constructor is marked as private, it can only be called from within the class. This allows the method getInstance to create a new instance-

self::$instance = new self();

But (as pointed out) if you tried to create an instance of this class in your own code - it will give an error as you can't call the private constructor.

This allows a class to restrict how instances of this object are created and therefore in this case limit it to 1 copy.

Nigel Ren
  • 56,122
  • 11
  • 43
  • 55