fbpx
Wikipedia

Singleton

En ingeniería de software, singleton o instancia única es un patrón de diseño que restringe la creación a un único objeto la creación de objetos pertenecientes a una clase y asegura de que sólo haya esta instancia única.

Diagrama UML de una clase que implementa el patrón singleton.

Además de garantizar que una clase solo tenga una instancia, proporcionar un punto de acceso global a ella.

El patrón singleton se implementa creando en nuestra clase un método que crea una instancia del objeto solo si todavía no existe alguna. Para asegurar que la clase no puede ser instanciada nuevamente se regula el alcance del constructor (con modificadores de acceso como protegido o privado).

La instrumentación del patrón puede ser delicada en programas con múltiples hilos de ejecución. Si dos hilos de ejecución intentan crear la instancia al mismo tiempo y esta no existe todavía, solo uno de ellos debe lograr crear el objeto. La solución clásica para este problema es utilizar exclusión mutua en el método de creación de la clase que implementa el patrón.

Las situaciones más habituales de aplicación de este patrón son aquellas en las que dicha clase controla el acceso a un recurso físico único (como puede ser el ratón o un archivo abierto en modo exclusivo) o cuando cierto tipo de datos debe estar disponible para todos los demás objetos de la aplicación.

Los críticos consideran al singleton como un anti-patrón utilizando en escenarios donde no es beneficioso, introduce restricciones innecesarias donde una única instancia de una clase no es realmente requerida y agrega un estado global en la aplicación.[1][2]

El patrón singleton provee una única instancia global gracias a que:

  • La propia clase es responsable de crear la única instancia. Por medio de su método constructor.
  • Permite el acceso global a dicha instancia mediante un método de clase.
  • Declara el constructor de clase como privado para que no sea instanciable directamente.
  • Al estar internamente autoreferenciada, en lenguajes como Java, el recolector de basura no actúa.

Ejemplo de implementación editar

ActionScript 3 editar

Una implementación del patrón singleton en ActionScript es la siguiente:

public class Singleton{  private static var instance:Singleton;  private static var allowInstance:Boolean;  public function Singleton(){  if(!allowInstance){  throw new Error("Debes usar getInstance()");  }else{  trace("Se inicializó una instancia de Singleton");  }  }   public static function getInstance():Singleton{  if(instance==null){  allowInstance=true;  instance= new Singleton();  allowInstance=false;  }else{  trace("Se regresa la instancia existente");  }  return instance;  } } 

Autoit editar

Una implementación del patrón singleton en Autoit es la siguiente:

#include <Misc.au3> if _Singleton("test",1) = 0 Then Msgbox(0,"Warning","An occurence of test is already running") Exit EndIf Msgbox(0,"OK","the first occurence of test is running") 

C# editar

Un ejemplo correcto de inicialización diferida y segura en entornos multi-hilo en C# sería:

public class Singleton {  // Variable estática para la instancia, se necesita utilizar una función lambda ya que el constructor es privado  private static readonly Lazy<Singleton> instance = new Lazy<Singleton>(() => new Singleton());  // Constructor privado para evitar la instanciación directa  private Singleton()  {  }  // Propiedad para acceder a la instancia  public static Singleton Instance  {  get  {  return instance.Value;  }  } } // Clase de prueba public class Prueba {  private static void Main(string[] args)  {  //Singleton s0 = new Singleton(); //Error  Singleton s1 = Singleton.Instance;  Singleton s2 = Singleton.Instance;  if(s1==s2)  {  // Misma instancia  }  } } 

C++ editar

Una solución posible en C++ (conocida como el singleton de Meyers) en la cual el singleton es un objeto local estático (notar que esta solución no es segura en programas multi-hilo):

template <class T> class Singleton {  public:  static T& Instance()  {  static T laInstanciaSingleton; //asumir T posee un constructor por defecto  return laInstanciaSingleton;  } }; class Singleton : public Singleton<Singleton> {  friend class Singleton<Singleton>; //para dar acceso al constructor privado de SoloUno  //..definir aquí el resto de la interfaz }; 

D editar

Una posible implementación en D sería:

final class Singleton {  private static Singleton instance;  static this() {  instance = new Singleton();  }  static Singleton opCall() {  return instance;  } } auto s1 = Singleton(); auto s2 = Singleton(); assert(s1 == s2); 

Delphi editar

Esta implementación ha sido sacada de [1] y está basada en la sobreescritura de los métodos NewInstance y FreeInstance que se hereda de la clase TObject, la madre de todos los objetos en Embarcadero Delphi.

type  TSingleton = class  public  class function NewInstance: TObject; override;  procedure FreeInstance; override;  class function RefCount: Integer;  end; var  Instance : TSingleton = nil;  Ref_Count : Integer = 0; 

Y su implementación sería así:

procedure TSingleton.FreeInstance; begin  Dec( Ref_Count );  if ( Ref_Count = 0 ) then  begin  Instance := nil;  // Destroy private variables here  inherited FreeInstance;  end; end; class function TSingleton.NewInstance: TObject; begin  if ( not Assigned( Instance ) ) then  begin  Instance := inherited NewInstance;  // Initialize private variables here, like this:  // TSingleton(Result).Variable := Value;  end;  Result := Instance  Inc( Ref_Count ); end; class function TSingleton.RefCount: Integer; begin  Result := Ref_Count; end; 

Java editar

La implementación más usual en el lenguaje de programación Java es la siguiente:

public class Singleton {  private static final Singleton INSTANCE = new Singleton();  // El constructor privado no permite que se genere un constructor por defecto.  // (con mismo modificador de acceso que la definición de la clase)   private Singleton() {}  public static Singleton getInstance() {  return INSTANCE;  } } 

Un ejemplo correcto de inicialización diferida. Se deja para comentar un error común en Java al no tener en cuenta la sincronización de métodos.

public class Singleton {  private static Singleton INSTANCE = null;  // Private constructor suppresses   private Singleton(){}  // creador sincronizado para protegerse de posibles problemas multi-hilo  // otra prueba para evitar instanciación múltiple   private synchronized static void createInstance() {  if (INSTANCE == null) {   INSTANCE = new Singleton();  }  }  public static Singleton getInstance() {  if (INSTANCE == null) createInstance();  return INSTANCE;  } } 

Si queremos reducir el coste de la sincronización, se realiza la comprobación de la instancia antes de invocar el método "createInstance"; también es posible hacerlo en un único método de la siguiente manera [2]:

 private static void createInstance() {  if (INSTANCE == null) {  // Solo se accede a la zona sincronizada  // cuando la instancia no está creada  synchronized(Singleton.class) {   // En la zona sincronizada sería necesario volver   // a comprobar que no se ha creado la instancia   if (INSTANCE == null) {    INSTANCE = new Singleton();   }  }  }  } 

Para asegurar que se cumpla el requerimiento de "única instancia" del singleton; la clase debería producir un objeto no clonable:

//Así se podría clonar el objeto y no tendría unicidad. SingletonObjectDemo clonedObject = (SingletonObjectDemo) obj.clone(); 

Entonces, se debería impedir la clonación sobreescribiendo el método "clone" de la siguiente manera:

//El método "clone" es sobreescrito por el siguiente que arroja una excepción: public Object clone() throws CloneNotSupportedException {  throw new CloneNotSupportedException();  } 

Otra cuestión a tener en cuenta es que los métodos (o la clase) deberían ser declarados como: final para que no puedan ser sobreescritos.

Existe otra implementación menos conocida, pero con mayores ventajas dentro de Java que es la siguiente:

public enum SingletonEnum {  INSTANCE;    int value;    public int getValue() {  return value;  }    public void setValue(int value) {  this.value = value;  } } 

Este enfoque es thread-safe y serializable, garantizado por la implementación de enum.

Ejemplo de uso:

public class EnumDemo {  public static void main(String[] args) {  SingletonEnum singleton = SingletonEnum.INSTANCE;  System.out.println(singleton.getValue());  singleton.setValue(2);  System.out.println(singleton.getValue());  } } 

Javascript editar

Una implementación del patrón singleton en Javascript es la siguiente:

Singleton = function Singleton$constructor() {  return {   getInstance : function Singleton$getInstance() {  return this;  }  }; }(); 

Objective C editar

Una sencilla implementación del patrón Singleton para el lenguaje Objective C es:

#import "Singleton.h"   @implementation Singleton   +(Singleton *) getInstance{  static Singleton* singleton = nil;  @synchronized(self){  if (!singleton) {  singleton = [self new];  }  }  return singleton; } @end 

Otra forma mejor utilizando GCD es:

+ (id)sharedInstance {  static dispatch_once_t pred = 0;  __strong static id _sharedObject = nil;  dispatch_once(&pred, ^{  _sharedObject = [[self alloc] init];  });  return _sharedObject; } 

Perl editar

Como es habitual en Perl, hay más de un forma de hacerlo. De entre varias posibilidades,[3]​ podemos señalar esta:

[Singleton.pm] package Singleton; my $singleton; sub new { my $class = shift; $singleton ||= bless {}, $class; } ... [foo.pl] require Singleton; my $object1 = new Singleton; my $object2 = new Singleton;# El mismo objeto 

PHP editar

Un ejemplo de implementación del patrón singleton en PHP sería la siguiente:

<?php class Singleton { // Contenedor Instancia de la clase private static $instance = null; // Constructor privado, previene la creación de instancias vía new private function __construct() { } // Clonación no permitida private function __clone() { } // Método singleton  public static function getInstance() { if (null === self::$instance) {  self::$instance = new Singleton(); } return self::$instance; } } 

Python editar

El siguiente es un ejemplo de implementación de Singleton en Python (tampoco es segura en la programación multi-hilo):

class Singleton (object): instance = None def __new__(cls, *args, **kargs): if cls.instance is None:  cls.instance = object.__new__(cls, *args, **kargs) return cls.instance #Usage mySingleton1 = Singleton() mySingleton2 = Singleton() #mySingleton1 y mySingleton2 son la misma instancia assert mySingleton1 is mySingleton2 

Y otra posibilidad interesante es implementarlo como una metaclase:

class Singleton(type): def __init__(cls, name, bases, dct): cls.__instance = None type.__init__(cls, name, bases, dct) def __call__(cls, *args, **kw): if cls.__instance is None:  cls.__instance = type.__call__(cls, *args,**kw) return cls.__instance class A: __metaclass__ = Singleton # Definir aquí el resto de la interfaz a1 = A() a2 = A() assert a1 is a2 

Visual Basic. NET editar

Una implementación del patrón singleton en Visual Basic .NET es la siguiente:

Public Class Singleton  Private Sub New() 'CONSTRUCTOR  End Sub  Private Shared instancia As Singleton = Nothing  Public Shared Function getInstancia As Singleton  If instancia Is Nothing Then   instancia = New Singleton()  End If  Return instancia  End Function End Class 

Patrones relacionados editar

  • Abstract Factory: muchas veces son implementados mediante singleton, ya que normalmente deben ser accesibles públicamente y debe haber una única instancia que controle la creación de objetos.
  • Monostate: es similar al singleton, pero en lugar de controlar el instanciado de una clase, asegura que todas las instancias tengan un estado común, haciendo que todos sus miembros sean de clase.

Enlaces externos editar

  •   Wikilibros alberga un libro o manual sobre Patrones de Comportamiento.
  • Patrón Singleton: explicación y modelo UML
  • (java.sun.com)
  • PEC(TM) (enlace roto disponible en Internet Archive; véase el historial, la primera versión y la última)., compilador que garantiza la correcta instrumentación del patrón singleton y de otros patrones.
  • Data&Object Factory, explicación e implementación en C# del patrón singleton.
  • Patrón Singleton explicado en video, artículo de Lucas Ontivero donde explica mediante tres videos de 8 minutos 3 implementaciones del patrón Singleton en CSharp (nivel básico)

Referencias editar

  1. «Singleton design pattern». HowToDoInJava (en inglés estadounidense). 22 de octubre de 2012. Consultado el 10 de julio de 2020. 
  2. Contieri, Maximiliano (11 de julio de 2020). «Singleton: El Patrón del mal». Medium (en inglés). Consultado el 11 de julio de 2020. 
  3. Cunningham & Cunningham, Inc. (ed.). «Perl Singleton» (en inglés). Consultado el 4 de septiembre de 2012. 
  •   Datos: Q746699
  •   Multimedia: Singleton pattern / Q746699

singleton, para, término, matemático, véase, conjunto, unitario, ingeniería, software, singleton, instancia, única, patrón, diseño, restringe, creación, único, objeto, creación, objetos, pertenecientes, clase, asegura, sólo, haya, esta, instancia, única, diagr. Para el termino matematico vease Conjunto unitario En ingenieria de software singleton o instancia unica es un patron de diseno que restringe la creacion a un unico objeto la creacion de objetos pertenecientes a una clase y asegura de que solo haya esta instancia unica Diagrama UML de una clase que implementa el patron singleton Ademas de garantizar que una clase solo tenga una instancia proporcionar un punto de acceso global a ella El patron singleton se implementa creando en nuestra clase un metodo que crea una instancia del objeto solo si todavia no existe alguna Para asegurar que la clase no puede ser instanciada nuevamente se regula el alcance del constructor con modificadores de acceso como protegido o privado La instrumentacion del patron puede ser delicada en programas con multiples hilos de ejecucion Si dos hilos de ejecucion intentan crear la instancia al mismo tiempo y esta no existe todavia solo uno de ellos debe lograr crear el objeto La solucion clasica para este problema es utilizar exclusion mutua en el metodo de creacion de la clase que implementa el patron Las situaciones mas habituales de aplicacion de este patron son aquellas en las que dicha clase controla el acceso a un recurso fisico unico como puede ser el raton o un archivo abierto en modo exclusivo o cuando cierto tipo de datos debe estar disponible para todos los demas objetos de la aplicacion Los criticos consideran al singleton como un anti patron utilizando en escenarios donde no es beneficioso introduce restricciones innecesarias donde una unica instancia de una clase no es realmente requerida y agrega un estado global en la aplicacion 1 2 El patron singleton provee una unica instancia global gracias a que La propia clase es responsable de crear la unica instancia Por medio de su metodo constructor Permite el acceso global a dicha instancia mediante un metodo de clase Declara el constructor de clase como privado para que no sea instanciable directamente Al estar internamente autoreferenciada en lenguajes como Java el recolector de basura no actua Indice 1 Ejemplo de implementacion 1 1 ActionScript 3 1 2 Autoit 1 3 C 1 4 C 1 5 D 1 6 Delphi 1 7 Java 1 8 Javascript 1 9 Objective C 1 10 Perl 1 11 PHP 1 12 Python 1 13 Visual Basic NET 2 Patrones relacionados 3 Enlaces externos 4 ReferenciasEjemplo de implementacion editarActionScript 3 editar Una implementacion del patron singleton en ActionScript es la siguiente public class Singleton private static var instance Singleton private static var allowInstance Boolean public function Singleton if allowInstance throw new Error Debes usar getInstance else trace Se inicializo una instancia de Singleton public static function getInstance Singleton if instance null allowInstance true instance new Singleton allowInstance false else trace Se regresa la instancia existente return instance Autoit editar Una implementacion del patron singleton en Autoit es la siguiente include lt Misc au3 gt if Singleton test 1 0 Then Msgbox 0 Warning An occurence of test is already running Exit EndIf Msgbox 0 OK the first occurence of test is running C editar Un ejemplo correcto de inicializacion diferida y segura en entornos multi hilo en C seria public class Singleton Variable estatica para la instancia se necesita utilizar una funcion lambda ya que el constructor es privado private static readonly Lazy lt Singleton gt instance new Lazy lt Singleton gt gt new Singleton Constructor privado para evitar la instanciacion directa private Singleton Propiedad para acceder a la instancia public static Singleton Instance get return instance Value Clase de prueba public class Prueba private static void Main string args Singleton s0 new Singleton Error Singleton s1 Singleton Instance Singleton s2 Singleton Instance if s1 s2 Misma instancia C editar Una solucion posible en C conocida como el singleton de Meyers en la cual el singleton es un objeto local estatico notar que esta solucion no es segura en programas multi hilo template lt class T gt class Singleton public static T amp Instance static T laInstanciaSingleton asumir T posee un constructor por defecto return laInstanciaSingleton class Singleton public Singleton lt Singleton gt friend class Singleton lt Singleton gt para dar acceso al constructor privado de SoloUno definir aqui el resto de la interfaz D editar Una posible implementacion en D seria final class Singleton private static Singleton instance static this instance new Singleton static Singleton opCall return instance auto s1 Singleton auto s2 Singleton assert s1 s2 Delphi editar Esta implementacion ha sido sacada de 1 y esta basada en la sobreescritura de los metodos NewInstance y FreeInstance que se hereda de la clase TObject la madre de todos los objetos en Embarcadero Delphi type TSingleton class public class function NewInstance TObject override procedure FreeInstance override class function RefCount Integer end var Instance TSingleton nil Ref Count Integer 0 Y su implementacion seria asi procedure TSingleton FreeInstance begin Dec Ref Count if Ref Count 0 then begin Instance nil Destroy private variables here inherited FreeInstance end end class function TSingleton NewInstance TObject begin if not Assigned Instance then begin Instance inherited NewInstance Initialize private variables here like this TSingleton Result Variable Value end Result Instance Inc Ref Count end class function TSingleton RefCount Integer begin Result Ref Count end Java editar La implementacion mas usual en el lenguaje de programacion Java es la siguiente public class Singleton private static final Singleton INSTANCE new Singleton El constructor privado no permite que se genere un constructor por defecto con mismo modificador de acceso que la definicion de la clase private Singleton public static Singleton getInstance return INSTANCE Un ejemplo correcto de inicializacion diferida Se deja para comentar un error comun en Java al no tener en cuenta la sincronizacion de metodos public class Singleton private static Singleton INSTANCE null Private constructor suppresses private Singleton creador sincronizado para protegerse de posibles problemas multi hilo otra prueba para evitar instanciacion multiple private synchronized static void createInstance if INSTANCE null INSTANCE new Singleton public static Singleton getInstance if INSTANCE null createInstance return INSTANCE Si queremos reducir el coste de la sincronizacion se realiza la comprobacion de la instancia antes de invocar el metodo createInstance tambien es posible hacerlo en un unico metodo de la siguiente manera 2 private static void createInstance if INSTANCE null Solo se accede a la zona sincronizada cuando la instancia no esta creada synchronized Singleton class En la zona sincronizada seria necesario volver a comprobar que no se ha creado la instancia if INSTANCE null INSTANCE new Singleton Para asegurar que se cumpla el requerimiento de unica instancia del singleton la clase deberia producir un objeto no clonable Asi se podria clonar el objeto y no tendria unicidad SingletonObjectDemo clonedObject SingletonObjectDemo obj clone Entonces se deberia impedir la clonacion sobreescribiendo el metodo clone de la siguiente manera El metodo clone es sobreescrito por el siguiente que arroja una excepcion public Object clone throws CloneNotSupportedException throw new CloneNotSupportedException Otra cuestion a tener en cuenta es que los metodos o la clase deberian ser declarados como final para que no puedan ser sobreescritos Existe otra implementacion menos conocida pero con mayores ventajas dentro de Java que es la siguiente public enum SingletonEnum INSTANCE int value public int getValue return value public void setValue int value this value value Este enfoque es thread safe y serializable garantizado por la implementacion de enum Ejemplo de uso public class EnumDemo public static void main String args SingletonEnum singleton SingletonEnum INSTANCE System out println singleton getValue singleton setValue 2 System out println singleton getValue Javascript editar Una implementacion del patron singleton en Javascript es la siguiente Singleton function Singleton constructor return getInstance function Singleton getInstance return this Objective C editar Una sencilla implementacion del patron Singleton para el lenguaje Objective C es import Singleton h implementation Singleton Singleton getInstance static Singleton singleton nil synchronized self if singleton singleton self new return singleton end Otra forma mejor utilizando GCD es id sharedInstance static dispatch once t pred 0 strong static id sharedObject nil dispatch once amp pred sharedObject self alloc init return sharedObject Perl editar Como es habitual en Perl hay mas de un forma de hacerlo De entre varias posibilidades 3 podemos senalar esta Singleton pm package Singleton my singleton sub new my class shift singleton bless class foo pl require Singleton my object1 new Singleton my object2 new Singleton El mismo objeto PHP editar Un ejemplo de implementacion del patron singleton en PHP seria la siguiente lt php class Singleton Contenedor Instancia de la clase private static instance null Constructor privado previene la creacion de instancias via new private function construct Clonacion no permitida private function clone Metodo singleton public static function getInstance if null self instance self instance new Singleton return self instance Python editar El siguiente es un ejemplo de implementacion de Singleton en Python tampoco es segura en la programacion multi hilo class Singleton object instance None def new cls args kargs if cls instance is None cls instance object new cls args kargs return cls instance Usage mySingleton1 Singleton mySingleton2 Singleton mySingleton1 y mySingleton2 son la misma instancia assert mySingleton1 is mySingleton2 Y otra posibilidad interesante es implementarlo como una metaclase class Singleton type def init cls name bases dct cls instance None type init cls name bases dct def call cls args kw if cls instance is None cls instance type call cls args kw return cls instance class A metaclass Singleton Definir aqui el resto de la interfaz a1 A a2 A assert a1 is a2 Visual Basic NET editar Una implementacion del patron singleton en Visual Basic NET es la siguiente Public Class Singleton Private Sub New CONSTRUCTOR End Sub Private Shared instancia As Singleton Nothing Public Shared Function getInstancia As Singleton If instancia Is Nothing Then instancia New Singleton End If Return instancia End Function End ClassPatrones relacionados editarAbstract Factory muchas veces son implementados mediante singleton ya que normalmente deben ser accesibles publicamente y debe haber una unica instancia que controle la creacion de objetos Monostate es similar al singleton pero en lugar de controlar el instanciado de una clase asegura que todas las instancias tengan un estado comun haciendo que todos sus miembros sean de clase Enlaces externos editar nbsp Wikilibros alberga un libro o manual sobre Patrones de Comportamiento Patron Singleton explicacion y modelo UML A Q amp A page java sun com PEC TM enlace roto disponible en Internet Archive vease el historial la primera version y la ultima compilador que garantiza la correcta instrumentacion del patron singleton y de otros patrones Data amp Object Factory explicacion e implementacion en C del patron singleton Patron Singleton explicado en video articulo de Lucas Ontivero donde explica mediante tres videos de 8 minutos 3 implementaciones del patron Singleton en CSharp nivel basico Referencias editar Singleton design pattern HowToDoInJava en ingles estadounidense 22 de octubre de 2012 Consultado el 10 de julio de 2020 Contieri Maximiliano 11 de julio de 2020 Singleton El Patron del mal Medium en ingles Consultado el 11 de julio de 2020 Cunningham amp Cunningham Inc ed Perl Singleton en ingles Consultado el 4 de septiembre de 2012 nbsp Datos Q746699 nbsp Multimedia Singleton pattern Q746699 Obtenido de https es wikipedia org w index php title Singleton amp oldid 154544338, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos