Singleton Pattern

I was asked about a singleton in an interview and well, I didn't have an answer then. I call for a rematch now! Anyway, in this article I explain what is a singleton through a problem. A singleton is basically a design pattern.

What even is a design pattern? Its a kernel to a solution. Yeah. It's not language agnostic. It's just a solution that helps in designing better code. There are many design patterns especially in the world of objects. Patterns work well with other patterns. They also have have their disadvantages. Patterns are good when used when needed.

What then is a singleton?

Problem-let's define a problem

Let's have a logging class where we need to write log information to one file. We want to perform this very often from a centralized place. I/O system calls are usually costly. Instantiating a class every time we need to write a file is not great. We are not centralizing. We need a way to create a global that is accessible to every other class that would need logging.

A singleton will help us with this problem.

Singleton - a class that is instantiated only once.

Now how does this help? Well this will act as your global variable. You will defined a singleton class that will be in charge of logging.

class Logger {
    private static $instance = null;
    private $logFile;

    private function __construct($logFile = 'app.log') {
        $this->logFile = $logFile;
    }

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

    public function log($message) {
        $date = date('Y-m-d H:i:s');
        file_put_contents($this->logFile, "$date - $message\n", FILE_APPEND);
    }
}

$logger = Logger::getInstance();
$logger->log("User logged in successfully.");
$logger->log("Error processing request: " . $error);

We have defined some PHP code. As we can see, we declare the following:
private constructor- This prevents direct instantiation from outside the class.

Static getInstance() method- This is a static method with access to only static properties. It checks whether an instance is present and returns it or instantiates one and returns it.

log method handles the writing.

With this we can see that we are able to write logs from one point in the application without defining a global variable.

We are also able to maintain the settings of the log file from one place.

It is also thread safe due to data integrity.

Problems

While this is a good pattern to use:

  • Global even as a singleton are prone to misuse. Be sure to use them well

  • It lets you bypass the lines of communication defined by interfaces therefore remain hidden away in methods and not class signature.

Moderate use of this patterns should be observed.

I hope you have seen a real use for a singleton. Cheers!