Одинак — це породжуючий патерн, який гарантує існування тільки одного об’єкта певного класу, а також дозволяє дістатися цього об’єкта з будь-якого місця програми.
Одинак має такі ж переваги та недоліки, що і глобальні змінні. Його неймовірно зручно використовувати, але він порушує модульність вашого коду.
Ви не зможете просто взяти і використовувати клас, залежний від одинака, в іншій програмі. Для цього доведеться емулювати там присутність одинака. Найчастіше ця проблема проявляється при написанні юніт-тестів.
Ознаки застосування патерна: Одинака можна визначити за статичним створюючим методом, який повертає один і той же об’єкт.
Наївний Одинак (один потік)
Незграбно реалізувати Одинака дуже просто — достатньо приховати конструктор і надати створюючий статичний метод.
Singleton.java: Одинак
DemoSingleThread.java: Клієнтський код
OutputDemoSingleThread.txt: Результати виконання
Наївний Одинак (багато потоків)
Той же клас веде себе неправильно в багатопотоковому середовищі. Декілька потоків можуть одночасно викликати метод отримання Одинака та створити відразу кілька екземплярів об’єкта.
Singleton.java: Одинак
DemoMultiThread.java: Клієнтський код
OutputDemoMultiThread.txt: Результати виконання
Багатопоточний Одинак
Щоб виправити проблему, потрібно синхронізувати потоки при створенні об’єкта-Одинака.
Singleton.java: Одинак
DemoMultiThread.java: Клієнтський код
OutputDemoMultiThread.txt: Результати виконання
Бажаєте ще?
Існує ще з півдюжини способів реалізації Одинака в Java. Якщо цікаво, можете ознайомитися з ними тут: