# 5.1 Singleton Classes

A singleton is a design pattern that restricts the instantation of a class to only one instance; a singleton class is a class that is defined in such a way that only one instance of the class can be created and used everywhere.

This is used when creating a central point of access for an application to access its data store. In Android this is very conveinient as many times we need an application to be able to access a central in-sync data store location from across many differant activities or fragments.

## Singleton Class Attributes:

1. **Only one instance:** The singleton class has only one instance. Also, outer classes and subclasses should be prevented to create the instance.
2. **Globally accessible:** The instance of the singleton class should be globally accessible so that each class can use it.

## **Rules for making a class Singleton**

The following rules are followed to make a Singleton class:

1. A private constructor
2. Globally accessible object reference
3. Consistency across multiple threads&#x20;

### Implementation

We can leverage using the object keyword. In Kotlin, `object` is a special class that only has one instance. If you create a class with the `object` keyword instead of `class`, the Kotlin compiler makes the constructor private, creates a static reference for the object, and initializes the reference in a static block, automatically fulfilling the singleton contract.

Contrary to a **`class`**, an **`object`** can’t have any constructor, but **`init`** blocks are allowed if some initialization code is needed.

Here's an example singleton of a simple counter:

```kotlin
object Counter {
    var counter: Int
        // Only allows retrival of the counter, 
        // setting restricted to only within Singleton
        private set
    
    // Optional init block if you need some initalization
    init {
        counter = 0
    }

    // Increments the counter and returns the new number after incrementing.
    fun incrementCounter(): Int {
        return ++counter
    }
    
    // Can define whatever member functions you want!
}
```

Now, the singleton can be easily invoked by writing the below code:

```kotlin
val counter = Counter
counter.incrementCounter()
```

`object` comes with a limitation: object declarations can not have constructors which means they can not take parameters.

#### What if we want to take in arguments?

We can leverage companion object to create a singleton class! In short, companion objects are singleton objects whose properties and functions are tied to a class but *not* to the instance of that class — basically like the “static” keyword in Java but with a twist.

Here's the equivalent object as a singleton class:

```kotlin
class Counter private constructor(private var counter: Int) {   
    fun incrementCounter(): Int {
        return this.counter++
    }
    
    // The only way to instantiate Counter is through our companion object!
    companion object {
        private var instance: Counter? = null
        
        // Use of synchronized helps prevent race conditions (which you may know
        // what this is if you've taken an operating systems class, if not don't
        // worry too much!)
        fun getInstance(param: Int): Counter = instance ?: synchronized(this) {
            instance ?: Counter(param).also { instance = it }
        }
    }
}
```

**Key things to note:**

* **Make sure that your constructor is private**
* **Add any data you are interested in as an argument to the constructor, expand the definition of getInstance if so.**

Now, the singleton can be easily invoked by writing the below code:

```kotlin
val counter = Counter.getInstance(0)
counter.incrementCounter()
```
