Singleton класс в Котлине

Если я хочу определить Singleton, это будет примерно так:

Синглтон - это шаблон разработки программного обеспечения, который гарантирует, что у класса есть только один экземпляр, а глобальная точка доступа к нему обеспечивается этим классом.

Шаблон Singleton гарантирует, что будет создан только один экземпляр, и он будет действовать как единая точка доступа, тем самым обеспечивая безопасность потоков.

В java-коде это будет выглядеть так:

public class Singleton {
    
    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

Но приведенные выше коды опасны, особенно если они используются в разных потоках. Если два потока обращаются к этому синглтону одновременно, могут быть сгенерированы два экземпляра этого объекта.

class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    private synchronized static void createInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
    }

    public static Singleton getInstance() {
        if (instance == null) createInstance();
        return instance;
    }
}

Ключевое слово synchronized гарантирует отсутствие пересечения потоков при создании экземпляра.

Если вы хотите воссоздать это в Kotlin, то код, близкий к нему, будет:

class Singleton private constructor() {
    
    private object HOLDER {
        val INSTANCE = Singleton()
    }

    companion object {
        val instance: Singleton by lazy { HOLDER.INSTANCE }
    }
}

В этом случае by lazy{} указывает, что он будет вычислен только при первом доступе. Оценка свойств lazy синхронизирована, значение вычисляется только в одном потоке, и все потоки будут видеть одно и то же значение.

В Kotlin по умолчанию реализовано указанное выше требование:

object Singleton

Ага!!!. Вот и все. Всего одна строка кода, и вы можете избежать всех этих строк кода. object - это просто тип данных с поточно-ориентированной одноэлементной реализацией.

Объявления объекта

object DataProviderManager {
    fun registerDataProvider(provider: DataProvider) {
        // ...
    }

    val allDataProviders: Collection<DataProvider>
        get() = // ...
}

Как и объявление переменной, объявление объекта не является выражением и не может использоваться в правой части оператора присваивания. Инициализация объявления объекта является потокобезопасной.

Для ссылки на объект мы используем его имя напрямую.

DataProviderManager.registerDataProvider(...)

У объектов могут быть супертипы:

object DefaultListener : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) { ... }

    override fun mouseEntered(e: MouseEvent) { ... }
}

Суммировать:

  • Для представления класса Singleton в Kotlin требуется только ключевое слово object.
  • Класс object может содержать свойства, функции и метод init.
  • Использование метода конструктора НЕ допускается.
  • Объект не может быть создан так же, как и класс.
  • Объект создается при первом использовании, обеспечивая ленивую инициализацию.
  • Object инициализация объявления является поточно-ориентированной.

Если вы хотите узнать о шаблоне Singleton в java, следуйте этой статье:



Если вам понравилась эта статья, возможно, вам понравятся и другие мои статьи.