Что такое Singleton и зачем он нужен?
Singleton - это шаблон проектирования. Представляет собой класс, у которого будет гарантированно только один экземпляр и доступ к этому экземпляру из любого места в коде.
С помощью сингельтона делают, например, логгирование или репозитарии с данными - это когда вам требуется общее хранилище данных для нескольких экранов (нескольких bloc'ов). Настройки приложения очень удобно так хранить.
Во Flutter пример сингельтона - это WidgetsBinding.instance. В общем это удобный шаблон, которым без затей пользуются программисты всего мира и мы с вами тоже начнём.
Как сделать Singelton на Dart?
Приватный конструктор класса
Первое, что нам нужно сделать - это чтобы нельзя было создавать экземпляры класса. Делаем приватный конструктор, на Dart это можно сделать поставив нижнее подчеркивание перед конструктором:
Отличненько! Правда мы теперь не можем создавать экземпляры...
Создаем instance нашего Singelton'а
Объявляем статическую переменную instance, в которой и будем хранить наш экземпляр класса:
Теперь в любом месте нашего приложения мы можем обращаться к MySingleton.instance - здорово! Вот мы и создали простейший сингельтон!
Как сделать Singelton ещё лучше?
Ленивый Singelton - создаем экземпляр только когда он нужен (при первом вызове)
Если мы не используем сингельтон, то нам и экземпляры его не нужны, логично? На самом деле - нет 😜 Если он нам не нужен, то зачем мы его создавали?
Проблема другая - бывает, создание экземпляра тащит за собой сложную логику. И чтобы не тормозить запуск приложения, его надо создавать отложено.
Решать это будем так - делаем геттер на получение инстанса, в котором создаем экземпляр если он еще не был создан:
Доступ сразу из конструктора (фабричный конструктор)
Как-то слишком длинно обращаться к нашему сингельтону - MySingleton.instance, давайте переделаем на короткий вариант MySingleton() - будет проще и нагляднее.
Второй момент - это при таком подходе можно легко добавить передачу чего нибудь в конструктор сингельтона (это конечно странно, но бывает требуется)
Как мы помним, конструктор у нас приватный, по этому делаем фабрику, которая будет возвращать всегда один и тот же инстанс (ну и создавать его при первом обращении):
Супер! Теперь можно обращаться к нему так MySingleton().getSomeData...
Что дальше?
Болванка сингельтона готова. Я предлагаю её засунуть сразу в сниппеты кода (лайф тейплейт в студии) - будет сподручнее создавать.
Дальше наполняем функционалом наш сингельтон.
Помните - эта штука не панацея, используйте её только к месту и только с умом. Это всё-таки глобальная переменная - со всеми вытекающими из этого минусами в плане управления, связности, проблем с многопоточностью.
Успешного кодинга!