Одиночка (шаблон проектирования)
Материал из Википедии — свободной энциклопедии
Одиночка, Singleton — шаблон проектирования, порождающий объекты.
Содержание |
[править] Цель
Гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа. Существенно то, что можно пользоваться именно экземпляром класса, так как при этом во многих случаях становится доступной более широкая функциональность. Например, к описанным компонентам класса можно обращаться через Интерфейс, если такая возможность поддерживается языком.
[править] Плюсы
- контролируемый доступ к единственному экземпляру;
- уменьшение числа имён;
- допускает уточнение операций и представления;
- допускает переменное число экземпляров;
- большая гибкость, чем у операций класса.
[править] Минусы
- глобальные объекты вредны для объектного программирования и приводят к написанию не масштабируемого проекта.
[править] Применение
- должен быть ровно один экземпляр некоторого класса, легко доступный всем клиентам;
- единственный экземпляр должен расширяться путем порождения подклассов, и клиентам нужно иметь возможность работать с расширенным экземпляром без модификации своего кода
[править] Пример реализации
[править] Пример Java
public class MySingleton { private static MySingleton ourInstance = null; private MySingleton () { } public static final MySingleton getInstance() { if( null == ourInstance ) ourInstance = new MySingleton(); return ourInstance; } }
[править] Пример C++
Возможная реализация на C++ (известная как синглтон Мейерса), где одиночка представляет собой статический локальный объект (важно: это решение не потоко-безопасно и приводится только для того, чтобы показать как устроен шаблон, а не для реального использования в крупномасштабных программных проектах).
template<typename T> class Singleton { public: static T& Instance() { static T theSingleInstance; // у класса T есть конструктор по умолчанию return theSingleInstance; } }; class OnlyOne : public Singleton<OnlyOne> { //.. интерфейс класса };
[править] Пример C#
using System; using System.Collections; using System.Threading; namespace Singleton { class MainApp { static void Main() { LoadBalancer b1 = LoadBalancer.Instance(); LoadBalancer b2 = LoadBalancer.Instance(); LoadBalancer b3 = LoadBalancer.Instance(); LoadBalancer b4 = LoadBalancer.Instance(); // Same instance? if (b1 == b2 && b2 == b3 && b3 == b4) { Console.WriteLine("Same instance\n"); } // All are the same instance -- use b1 arbitrarily // Load balance 15 server requests for (int i = 0; i < 15; i++) { Console.WriteLine(b1.Server); } // Wait for user Console.Read(); } } // "Singleton" class LoadBalancer { private static LoadBalancer instance; private ArrayList servers = new ArrayList(); private Random random = new Random(); // Lock synchronization object private static object syncLock = new object(); // Constructor (protected) protected LoadBalancer() { // List of available servers servers.Add("ServerI"); servers.Add("ServerII"); servers.Add("ServerIII"); servers.Add("ServerIV"); servers.Add("ServerV"); } public static LoadBalancer Instance() { // Support multithreaded applications through // 'Double checked locking' pattern which (once // the instance exists) avoids locking each // time the method is invoked if (instance == null) { lock (syncLock) { if (instance == null) { instance = new LoadBalancer(); } } } return instance; } // Simple, but effective random load balancer public string Server { get { int r = random.Next(servers.Count); return servers[r].ToString(); } } } }
[править] Пример PHP 4
<?php class Singleton { function Singleton( $directCall = true ) { if ( $directCall ) { trigger_error("Нельзя использовать конструктор для создания класса Singleton. Используйте статический метод getInstance ()",E_USER_ERROR); } //TODO: Добавьте основной код конструктора здесь } function &getInstance() { static $instance; if ( !is_object( $instance ) ) { $instance = new Singleton( false ); } return $instance; } } ?>
[править] Пример PHP 5
<?php class Singleton { // object instance private static $instance; private function __construct() {} private function __clone() {} public static function getInstance() { if (self::$instance === null) { self::$instance = new self; } return self::$instance; } public function doAction() { ... } } //usage Singleton::getInstance()->doAction(); ?>
[править] Пример на Delphi
unit Unit1; interface type TSingleton = class strict private constructor Create; class var FInstance: TSingleton; public class function GetInstance: TSingleton; end; implementation constructor TSingleton.Create; begin inherited; end; class function TSingleton.GetInstance: TSingleton; begin if FInstance = nil then begin FInstance := TSingleton.Create(); end; Result := FInstance; end; end.
[править] Пример на языке Io
Singleton := Object clone Singleton clone := Singleton
[править] Пример на языке Ruby
class private_class_method :new # прячем стандартный метод new @@instance = nil def self.getInstance @@instance = new unless @@instance @@instance end end
[править] Ссылки
- Реализация наследования от Singleton - пример для PHP5
- Паттерн Singleton (Одиночка) — пример использования шаблона (C++).
- Одиночка — простое описание с примером применения.
- Реализация синглтонов — пример для Delphi.
- Шаблон Singleton — пример для Java.
порождающие шаблоны проектирования |
абстрактная фабрика | строитель | фабричный метод | прототип | одиночка | ленивая инициализация |
Это незавершённая статья о компьютерных языках. Вы можете помочь проекту, исправив и дополнив её. |