¿Diferencia entre clase estática y patrón singleton?

1769

¿Qué diferencia real (es decir, práctica) existe entre una clase estática y un patrón singleton?

Ambos pueden invocarse sin instanciación, ambos proporcionan solo una "Instancia" y ninguno de ellos es seguro para subprocesos. ¿Hay alguna otra diferencia?

Jorge Córdoba
fuente
44
Dependiendo de la implementación del lenguaje y sus patrones de uso, un Singleton podría ser menos eficiente debido a la sobrecarga de llamar al getInstance()método cada vez que quiera usarlo (aunque probablemente en la mayoría de los casos no importa ).
demasiado php
55
Ya hay muchas respuestas. En realidad, es un singletonobjeto donde los staticmétodos son solo funciones, una entidad no OO.
fastcodejava
44
Depende de la implementación. Csharpindepth.com/Articles/General/Singleton.aspx
VJAI
44
Hay una diferencia cuando desea permitir que terceros proporcionen la implementación de la clase. En este caso, generalmente también necesita un patrón de fábrica. Ver agiletribe.wordpress.com/2013/10/08/…
AgilePro
En mi opinión, esta respuesta lo resume muy bien stackoverflow.com/questions/14097656/…
Dave

Respuestas:

1251

¿Qué te hace decir que un método singleton o estático no es seguro para subprocesos? Por lo general, ambos deben implementarse para ser seguros para subprocesos.

La gran diferencia entre un singleton y un montón de métodos estáticos es que los singletons pueden implementar interfaces (o derivarse de clases base útiles, aunque eso es menos común, en mi experiencia), por lo que puede pasar el singleton como si fuera "simplemente otro "implementación.

Jon Skeet
fuente
29
Bueno, si lo prefiere, ninguno de los dos es inherentemente seguro para los hilos, debe hacer que sean seguros para ambos hilos, por lo que no hay diferencia allí.
Jorge Córdoba
119
¿Puedes dar un ejemplo de algo que sea inherentemente seguro para hilos, aparte de los tipos inmutables?
Jon Skeet
26
Para Skeet: las personas que dicen que singleton no es seguro para subprocesos significan que un singleton se comparte entre subprocesos innecesariamente todo el tiempo, mientras que los objetos de pila se comparten cuando los necesita, lo que significa que no tiene que hacer una sincronización innecesaria.
45
@ Geek: Imagina que el singleton implementa una interfaz Fooy tienes un método que toma Fooun parámetro. Con esa configuración, las personas que llaman pueden elegir usar el singleton como implementación, o podrían usar una implementación diferente. El método está desacoplado del singleton. Compare eso con la situación en la que la clase solo tiene métodos estáticos: cada parte del código que desea llamar a esos métodos está estrechamente acoplada a la clase, porque necesita especificar qué clase contiene los métodos estáticos.
Jon Skeet
10
@AmirBareket: Sin embargo, no es un singleton de acuerdo con el patrón de diseño de singleton; si la clase en sí misma permite crear múltiples instancias, no es un IMO de singleton, independientemente de lo que haga la fábrica.
Jon Skeet
476

La verdadera respuesta es de Jon Skeet, en otro foro aquí .

Un singleton permite el acceso a una única instancia creada: esa instancia (o más bien, una referencia a esa instancia) puede pasarse como parámetro a otros métodos y tratarse como un objeto normal.

Una clase estática solo permite métodos estáticos.

Kezzer
fuente
64
Sin embargo, ¿por qué pasaría un Singleton como parámetro si puede acceder a la misma instancia desde cualquier lugar llamando al método estático getInstance ()?
Henrique Ordine
23
@HenriqueOrdine ¿Entonces puede encajar en el código existente y proporcionar una interfaz?
66
@HenriqueOrdine Están hablando de una clase estática, no de una clase con métodos estáticos. La clase estática no puede ser instanciada. Sin embargo, si pasa una instancia de una clase (no estática) que contiene métodos estáticos, no puede llamar a métodos estáticos en una instancia.
Goran
3
¿Qué es una clase estática? Al menos en Java, no existe tal cosa.
Henrique Ordine
16
@Goran Al principio estaba muy confundido por tu redacción. Dijiste "no puedes llamar a métodos estáticos en una instancia". Lo leí como "si tiene una referencia a un objeto instanciado, no puede llamar a ningún método estático que pueda tener". Eso es, por supuesto, incorrecto. Después de leerlo varias veces, creo que quiso decir "desde dentro de métodos estáticos no se puede acceder a objetos no estáticos en la clase", lo cual es correcto. Queremos aclarar que para cualquier persona nueva en estos conceptos que encuentre esta respuesta y lea sus comentarios.
Andrew Steitz el
359
  1. Los objetos Singleton se almacenan en el montón , pero los objetos estáticos se almacenan en la pila .
  2. Podemos clonar (si el diseñador no lo rechazó) el objeto singleton, pero no podemos clonar el objeto de clase estática.
  3. Las clases Singleton siguen los OOP (principios orientados a objetos), las clases estáticas no.
  4. Podemos implementar un interfacecon una clase Singleton, pero los métodos estáticos de una clase (o, por ejemplo, un C # static class) no pueden.
Vadluri Sreenu
fuente
100
La segunda afirmación es incorrecta. No podemos clonar un objeto Singleton. La implementación de Singleton debe rechazar esto. Si realmente puedes clonar Singleton, no es Singleton.
Alexander Yancharuk
19
Esta respuesta no es correcta para Java: ni el singleton ni el static usan la pila.
AgilePro
72
# 1 no es importante. # 2 describe una implementación defectuosa. # 3 es completamente injustificable.
Casey
31
¿Cómo se puede almacenar el objeto estático en la pila? Se crea un nuevo marco de pila cuando invoca un método, almacena las variables locales del método, este marco de pila se elimina cuando el método regresa y esas variables locales se pierden. Claro que la pila es rápida, pero no es adecuada para almacenar objetos estáticos.
mike_m
23
No puedo entender la cantidad de votos a favor en este caso. 1) ¿Por qué Singleton debe almacenarse en la pila? En lenguajes administrados como C # o Java, los datos se almacenan en un montón administrado, a excepción de las variables / parámetros de métodos locales. 2) Si puede clonarlo, entonces no es un singleton implementado correctamente. 3) Singleton se conoce como un anti-patrón OOP; es decir, algo que debe evitar si es posible. 4) Esto es lo único correcto.
Groo
152

El patrón Singleton tiene varias ventajas sobre las clases estáticas. Primero, un singleton puede extender clases e implementar interfaces, mientras que una clase estática no puede (puede extender clases, pero no hereda sus miembros de instancia). Un singleton se puede inicializar de forma lenta o asincrónica, mientras que una clase estática generalmente se inicializa cuando se carga por primera vez, lo que genera posibles problemas con el cargador de clases. Sin embargo, la ventaja más importante es que los singletons pueden manejarse polimórficamente sin obligar a sus usuarios a suponer que solo hay una instancia.

neil.johnson
fuente
10
+1 para puntos buenos y pragmáticos. El patrón Singleton se usa en exceso en general, pero hay algunas situaciones en las que se ajusta. Ver también: agiletribe.wordpress.com/2013/10/08/…
AgilePro
3
Tienes razón sobre la ventaja de ser polimórfico. Este es el punto más importante
Ahmad el
La clase estática anidada puede implementar la interfaz. Intenta codificarlo, funcionará. Podría compilar el código sin ningún error.
nanosoft
75

staticLas clases no son para nada que necesite estado. Es útil para poner un montón de funciones juntas, es decir Math(o Utilsen proyectos). Entonces, el nombre de la clase solo nos da una pista donde podemos encontrar las funciones y nada más.

Singletones mi patrón favorito y lo uso para administrar algo en un solo punto. Es más flexible que las staticclases y puede mantener su estado. Puede implementar interfaces, heredar de otras clases y permitir la herencia.

Mi regla para elegir entre staticy singleton:

Si hay un montón de funciones que deben mantenerse juntas, entonces statices la opción. Cualquier otra cosa que necesite acceso único a algunos recursos, podría implementarse como a singleton.

Xaqron
fuente
16
¿Por qué las clases estáticas no deben hacer nada que necesite guardar el estado?
Trispedó
12
@Trisped: no tiene control preciso sobre la inicialización ni la finalización.
Xaqron
77
me perdiste en "Singleton es mi patrón favorito". Singleton es una esquina tan afilada que debería considerarse tanto un antipatrón como un patrón. Las clases bien pueden tener estados estáticos, eso también es acceso único, si algo el estado estático es más "acceso único" que singletons porque la mayoría de las implementaciones de singleton están rotas, es decir. puede clonar el singleton, mientras que static está bendecida por la definición de ser única.
PoweredByRice
1
¿Qué significa mantener el estado? ¿Qué es el estado?
Kyle Delaney
2
@KyleDelaney: Simplemente Statees la combinación de diferentes propiedades de un objeto que generalmente cambian con el tiempo. Puedes buscar en Google para una definición formal.
Xaqron
65

Clase estática: -

  1. No puede crear la instancia de la clase estática.

  2. Cargado automáticamente por .NET Framework Common Language Runtime (CLR) cuando se carga el programa o el espacio de nombres que contiene la clase.

  3. La clase estática no puede tener un constructor.

  4. No podemos pasar la clase estática al método.

  5. No podemos heredar la clase estática a otra clase estática en C #.

  6. Una clase que tiene todos los métodos estáticos.

  7. Mejor rendimiento (los métodos estáticos están unidos en tiempo de compilación)

Único:-

  1. Puede crear una instancia del objeto y reutilizarlo.

  2. La instancia de Singleton se crea por primera vez cuando el usuario lo solicitó.

  3. La clase Singleton puede tener un constructor.

  4. Puede crear el objeto de la clase singleton y pasarlo al método.

  5. La clase Singleton no dice ninguna restricción de herencia.

  6. Podemos disponer los objetos de una clase singleton pero no de clase estática.

  7. Los métodos pueden ser anulados.

  8. Se puede cargar lentamente cuando sea necesario (las clases estáticas siempre se cargan).

  9. Podemos implementar la interfaz (la clase estática no puede implementar la interfaz).

RajeshVerma
fuente
13
Las clases estáticas tienen constructores: msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
Tomer Arazy
2
Sí, static puede tener un constructor que es interno a esa clase. Esto se invoca cuando se llama a cualquier método estático en la clase.
rahulmr
Para singleton en tiempo de compilación, se almacena en la memoria HEAP, pero si se instancia una vez, ¿se almacena en STACK?
Luminous_Dev
@Luminous_Dev No. Cualquier instancia de singleton es una instancia de objeto al final del día. Se almacenará en el montón sin duda.
RBT
1
@rahulmr Distinción importante: el constructor también se invoca antes de que se cree la primera instancia (solo AKA).
CoolOppo
53

Una clase estática es aquella que solo tiene métodos estáticos, para los cuales una palabra mejor sería "funciones". El estilo de diseño incorporado en una clase estática es puramente de procedimiento.

Singleton, por otro lado, es un patrón específico para el diseño OO. Es una instancia de un objeto (con todas las posibilidades inherentes a eso, como el polimorfismo), con un procedimiento de creación que garantiza que solo haya una instancia de ese rol en particular durante toda su vida.

Morendil
fuente
1
polimorfismo no entra en juego con embarazos únicos en absoluto
32
Eso crees. Pienso diferente ;) Por ejemplo, imagine una fábrica de singleton que devuelve una interfaz. Sabes que estás obteniendo un ISingleton (y es el mismo para siempre) pero no necesariamente qué implementación.
Morendil
La clase estática anidada también puede tener métodos de instancia, no está restringida a tener solo métodos estáticos. Codifíquela y podrá ver.
nanosoft
En lenguajes con un modelo de objeto más agradable (por ejemplo, Ruby), las clases también son objetos. El aspecto "puramente procesal" de una clase estática es una restricción arbitraria impuesta por el lenguaje.
Max
36

En el patrón singleton puede crear el singleton como una instancia de un tipo derivado, no puede hacerlo con una clase estática.

Ejemplo rápido:

if( useD3D )
    IRenderer::instance = new D3DRenderer
else
    IRenderer::instance = new OpenGLRenderer
Don Neufeld
fuente
39
No es realmente un patrón singleton, se parece más a la fábrica para mí.
vava
10
En realidad no, la diferencia fundamental entre los dos es que el Singleton "cacheará" su único objeto y seguirá devolviendo (una referencia a) el mismo. El patrón Factory creará nuevas instancias.
Mystic
12
Entonces es proxy-singleton :)
vava
3
Hmm, conozco esta variedad de Singleton como MonoState.
Huppie
ejemplo es el patrón de fábrica
Rajavel D
26

Para ampliar la respuesta de Jon Skeet

La gran diferencia entre un singleton y un montón de métodos estáticos es que los singletons pueden implementar interfaces (o derivarse de clases base útiles, aunque eso es menos común IME), por lo que puede pasar el singleton como si fuera "simplemente otra" implementación.

Los singletons son más fáciles de trabajar cuando la unidad prueba una clase. Dondequiera que pase singletons como parámetro (constructores, setters o métodos), puede sustituir una versión simulada o tropezada del singleton.

Mike Rylander
fuente
No creo que puedas burlarte directamente de un singleton. ¿No debería declarar una interfaz que implementan el singleton y la clase simulada?
Ellen Spertus
@espertus ¿Por qué no puedes burlarte de tu singleton? Ejemplo usando mockito MySingleton mockOfMySingleton = mock(MySingleton.class).
Mike Rylander
tienes razón, puedes burlarte de él con herramientas como mockito que usan la reflexión. Quise decir que no puedes burlarte directamente subclasificándolo y anulando sus métodos.
Ellen Spertus
@espertus ¿Por qué no? Cuando crea una instancia del objeto que está probando, puede sustituir la implementación de la subclase de su singleton donde haya utilizado el original. Ej:new ClazzToTest(mockSingleton);
Mike Rylander
No he usado Mockito, pero ¿cómo puedes subclasificar una clase que tiene un constructor privado, como es el caso de los singletons, excepto mediante el uso de la reflexión? Discusiones relacionadas: stackoverflow.com/questions/2302179/mocking-a-singleton-class stackoverflow.com/questions/15939023/…
Ellen Spertus
23

Aquí hay un buen artículo: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html

Clases estáticas

  • Una clase que tiene todos los métodos estáticos .
  • Mejor rendimiento (los métodos estáticos están unidos en tiempo de compilación)
  • no puede anular los métodos, pero puede usar el método de ocultación. ( ¿Qué es el método oculto en Java? Incluso la explicación de JavaDoc es confusa )

    public class Animal {
        public static void foo() {
            System.out.println("Animal");
        }
    }
    
    public class Cat extends Animal {
        public static void foo() {  // hides Animal.foo()
            System.out.println("Cat");
        }
    }
    

único

En resumen, solo usaría clases estáticas para mantener métodos utilitarios y usar Singleton para todo lo demás.


Ediciones

JackDev
fuente
44
No sé sobre Java, pero en .Net, sus dos últimos puntos son incorrectos. Las clases estáticas pueden hacer referencia a propiedades y campos estáticos, por lo que en estado son iguales. Y tienen carga lenta: el constructor estático se ejecuta cuando: 1) Se crea una instancia de la clase. 2) Se hace referencia a cualquiera de los miembros estáticos de la clase. 1 no aplica, lo que deja 2. Entonces, una clase estática no se carga hasta la primera vez que se usa.
jmoreno
1
Para la clase estática, aunque no puede anular el método estático, puede ocultar el método estático de su padre.
Max Peng
si Animal animal = new Cat();entonces animal.foo();que pasa?
Luminous_Dev
¿La clase estática @jmoreno no se carga hasta el primer uso? Creo que se almacena en la memoria de la pila en tiempo de compilación. Y se accede instantáneamente ... ¿no?
Luminous_Dev
@Luminous_Dev: al menos para .net, una clase estática tiene un constructor que se ejecuta cuando se accede por primera vez, por lo que no, no es accesible al instante. El constructor estático podría, en teoría, tomar una cantidad de tiempo ilimitada. Donde (o cualquier otra clase se almacena) es un detalle de implementación, que no es realmente relevante para esta pregunta.
jmoreno
22

Otra ventaja de un singleton es que se puede serializar fácilmente, lo que puede ser necesario si necesita guardar su estado en el disco o enviarlo a algún lugar de forma remota.

Alex
fuente
19

No soy un gran teórico de OO, pero por lo que sé, creo que la única característica de OO que carecen de clases estáticas en comparación con Singletons es el polimorfismo. Pero si no lo necesita, con una clase estática, por supuesto, puede tener herencia (no estoy seguro acerca de la implementación de la interfaz) y encapsulación de datos y funciones.

El comentario de Morendil, "El estilo de diseño incorporado en una clase estática es puramente de procedimiento" Puedo estar equivocado, pero no estoy de acuerdo. En los métodos estáticos, puede acceder a miembros estáticos, que serían exactamente lo mismo que los métodos singleton que acceden a sus miembros de instancia única.

editar: en
realidad estoy pensando ahora que otra diferencia es que una clase estática se instancia al inicio del programa * y vive durante toda la vida útil del programa, mientras que un singleton se instancia explícitamente en algún momento y también puede destruirse.

* o puede ser instanciado en el primer uso, según el idioma, creo.

Petruza
fuente
15
Sí, todos los demás parecen ignorar el hecho de que una clase con métodos estáticos también puede tener campos estáticos privados que aún puede usar para mantener el estado (y exponer algunos de ellos al código del cliente a través de setters / getters estáticos públicos).
user289463
17

Para ilustrar el punto de Jon, lo que se muestra a continuación no se puede hacer si Logger era una clase estática. La clase SomeClassespera ILoggerque se pase una instancia de implementación a su constructor.

La clase Singleton es importante para que sea posible la inyección de dependencia.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            var someClass = new SomeClass(Logger.GetLogger());
        }


    }

    public class SomeClass 
    {
        public SomeClass(ILogger MyLogger)
        {

        }
    }

    public class Logger : ILogger
    {
        private static Logger _logger;
        private Logger() { }

        public static Logger GetLogger()
        {
            if (_logger==null)
            {
                _logger = new Logger();
            }

            return _logger;
        }

        public void Log()
        {

        }

    }


    public interface ILogger
    {
         void Log();
    }
}
desarrollador747
fuente
13

Bueno, un singleton es solo una clase normal que se instancia pero solo una vez e indirectamente del código del cliente. La clase estática no se instancia. Hasta donde sé, los métodos estáticos (la clase estática debe tener métodos estáticos) son más rápidos que los no estáticos.

Editar:
Descripción de la regla de rendimiento de FxCop: "Los métodos que no acceden a datos de instancia o métodos de instancia de llamada pueden marcarse como estáticos (Compartidos en VB). Después de hacerlo, el compilador emitirá sitios de llamadas no virtuales a estos miembros que evitarán un verifique en tiempo de ejecución para cada llamada que asegure que el puntero del objeto actual no sea nulo. Esto puede resultar en una ganancia de rendimiento medible para el código sensible al rendimiento. En algunos casos, la falla al acceder a la instancia del objeto actual representa un problema de corrección ".
No sé si esto también se aplica a los métodos estáticos en clases estáticas.

agnieszka
fuente
11

Los Singleton's son instanciados, solo hay una instancia instanciada, de ahí el single en Singleton.

Una clase estática no puede ser instanciada por nada más que por sí misma.

Kezzer
fuente
La clase estática puede ser muy instanciada en Java. Lea docs.oracle.com/javase/tutorial/java/javaOO/nested.html. Consulte también mi respuesta stackoverflow.com/a/37114702/1406510
nanosoft
8

Las principales diferencias son:

  • Singleton tiene una instancia / objeto, mientras que la clase estática es un montón de métodos estáticos
  • Singleton se puede extender, por ejemplo, a través de una interfaz, mientras que la clase estática no se puede.
  • Singleton se puede heredar, lo que admite principios abiertos / cerrados en principios SOLID, por otro lado, la clase estática no se puede heredar y debemos realizar cambios en sí misma.
  • El objeto Singleton se puede pasar a métodos, mientras que la clase estática, ya que no tiene instancia, no se puede pasar como parámetros
Faran Shabbir
fuente
7

Singleton es un mejor enfoque desde la perspectiva de la prueba. A diferencia de las clases estáticas, singleton podría implementar interfaces y puede usar simulacros de instancia e inyectarlos.

En el siguiente ejemplo ilustraré esto. Suponga que tiene un método isGoodPrice () que usa un método getPrice () e implementa getPrice () como método en un singleton.

Singleton que proporciona la funcionalidad getPrice:

public class SupportedVersionSingelton {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        // calculate price logic here
        return 0;
    }
}

Uso de getPrice:

public class Advisor {

    public boolean isGoodDeal(){

        boolean isGoodDeal = false;
        ICalculator supportedVersion = SupportedVersionSingelton.getInstance();
        int price = supportedVersion.getPrice();

        // logic to determine if price is a good deal.
        if(price < 5){
            isGoodDeal = true;
        }

        return isGoodDeal;
    }
}


In case you would like to test the method isGoodPrice , with mocking the getPrice() method you could do it by:
Make your singleton implement an interface and inject it. 



  public interface ICalculator {
        int getPrice();
    }

Implementación final de Singleton:

public class SupportedVersionSingelton implements ICalculator {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        return 0;
    }

    // for testing purpose
    public static void setInstance(ICalculator mockObject){
        if(instance != null ){
instance = mockObject;
    }

clase de prueba:

public class TestCalculation {

    class SupportedVersionDouble implements ICalculator{
        @Override
        public int getPrice() { 
            return 1;
        }   
    }
    @Before
    public void setUp() throws Exception {
        ICalculator supportedVersionDouble = new SupportedVersionDouble();
        SupportedVersionSingelton.setInstance(supportedVersionDouble);

    }

    @Test
    public void test() {
          Advisor advidor = new Advisor();
          boolean isGoodDeal = advidor.isGoodDeal();
          Assert.assertEquals(isGoodDeal, true);

    }

}

En caso de que tomemos la alternativa de usar un método estático para implementar getPrice (), fue difícil burlarse de getPrice (). Puede simular estática con simulación de potencia, pero no todos los productos pueden usarla.

Amir Bareket
fuente
1
Eso ahora no es seguro para subprocesos, y generalmente desagradable en términos de cómo accede a la implementación de la interfaz. Claro, tener una interfaz es bueno para la capacidad de prueba, pero ¿por qué molestarse con un singleton? Solo evita tener un singleton; haga que una clase lo implemente para fines de producción, una implementación para fines de prueba e inyecte la instancia correcta según lo que esté haciendo. No es necesario acoplar el singleton a sus llamadores en absoluto.
Jon Skeet
Gracias por la respuesta. Es muy sencillo hacerlo seguro para subprocesos. Además, uso Singleton para el almacenamiento en caché.
Amir Bareket
1
Sí, aunque con una sobrecarga inútil. De nuevo, es más simple no usar un singleton.
Jon Skeet
6

Estoy de acuerdo con esta definición:

La palabra " único " significa un solo objeto en todo el ciclo de vida de la aplicación, por lo que el alcance está en el nivel de la aplicación.

La estática no tiene ningún puntero de objeto, por lo que el alcance está en el nivel de dominio de aplicación.

Además, ambos deben implementarse para ser seguros para subprocesos.

Puede encontrar otras diferencias interesantes sobre: Patrón Singleton Versus Clase Estática

Alessandro Ornano
fuente
5

Una diferencia notable es la instanciación diferente que viene con Singletons.

Con las clases estáticas, CLR lo crea y no tenemos control sobre él. con singletons, el objeto se instancia en la primera instancia a la que se intenta acceder.

Eranga Dissanayaka
fuente
4

En muchos casos, estos dos no tienen una diferencia práctica, especialmente si la instancia de singleton nunca cambia o cambia muy lentamente, por ejemplo, manteniendo las configuraciones.

Yo diría que la mayor diferencia es que un singleton sigue siendo un Java Bean normal, en oposición a una clase Java solo estática especializada. Y debido a esto, un singleton es aceptado en muchas más situaciones; De hecho, es la estrategia de instanciación predeterminada de Spring Framework. El consumidor puede o no saber que se está pasando un singleton, solo lo trata como un bean Java normal. Si los requisitos cambian y un singleton necesita convertirse en un prototipo, como vemos a menudo en Spring, se puede hacer sin problemas sin una línea de cambio de código para el consumidor.

Alguien más ha mencionado anteriormente que una clase estática debería ser puramente de procedimiento, por ejemplo, java.lang.Math. En mi opinión, una clase de este tipo nunca debe pasarse y nunca deben tener nada más que atributos finales estáticos. Para todo lo demás, use un singleton ya que es mucho más flexible y más fácil de mantener.

Chris
fuente
4

Tenemos nuestro marco de trabajo de base de datos que hace conexiones al back-end. Para evitar lecturas sucias en múltiples usuarios, hemos utilizado un patrón único para asegurarnos de tener una única instancia disponible en cualquier momento.

En c #, una clase estática no puede implementar una interfaz. Cuando una clase de instancia única necesita implementar una interfaz para contratos comerciales o propósitos de IoC, aquí es donde uso el patrón Singleton sin una clase estática

Singleton proporciona una manera de mantener el estado en escenarios sin estado

Espero que te ayude ..

RK_Muddala
fuente
3
  1. Carga lenta
  2. Soporte de interfaces, de modo que se pueda proporcionar una implementación separada
  3. Capacidad para devolver el tipo derivado (como una combinación de carga diferida e implementación de interfaz)
Tilak
fuente
La clase estática anidada puede implementar mucho la interfaz en Java. Tu segundo punto es incorrecto.
nanosoft
3

a. Serialización: los miembros estáticos pertenecen a la clase y, por lo tanto, no se pueden serializar.

si. Aunque hemos hecho que el constructor sea privado, las variables miembro estáticas aún se llevarán a la subclase.

C. No podemos hacer una inicialización diferida, ya que todo se cargará solo al cargar la clase.

Vivek Vermani
fuente
3

Desde la perspectiva del cliente, el comportamiento estático es conocido por el cliente, pero el comportamiento Singleton puede completarse oculto para un cliente. Es posible que el cliente nunca sepa que hay una sola instancia con la que juega una y otra vez.

Arpit Khandelwal
fuente
3

Leí lo siguiente y creo que también tiene sentido:

Cuidar de los negocios

Recuerde, una de las reglas OO más importantes es que un objeto es responsable de sí mismo. Esto significa que los problemas relacionados con el ciclo de vida de una clase deben manejarse en la clase, no delegarse en construcciones de lenguaje como estática, etc.

del libro Proceso de pensamiento orientado a objetos 4ª ed.

nonopolaridad
fuente
No estaría de acuerdo, ya que esto realmente solo agrega una responsabilidad a la clase, lo que (suponiendo que haga algo) significa que ahora viola el Principio de Responsabilidad Única.
ssmith
3

En un artículo que escribí, describí mi punto de vista sobre por qué el singleton es mucho mejor que una clase estática:

  1. La clase estática no es en realidad una clase canónica: es un espacio de nombres con funciones y variables
  2. Usar una clase estática no es una buena práctica debido a la ruptura de los principios de programación orientada a objetos.
  3. La clase estática no se puede pasar como parámetro para otro
  4. La clase estática no es adecuada para la inicialización "perezosa"
  5. La inicialización y el uso de la clase estática siempre tienen problemas
  6. Implementar la gestión de subprocesos es difícil
Paul R
fuente
Lo repasaría para la gramática inglesa, pero de lo contrario, es una lectura interesante :)
Noctis
3
  1. Podemos crear el objeto de la clase singleton y pasarlo al método.

  2. La clase Singleton no tiene ninguna restricción de herencia.

  3. No podemos deshacernos de los objetos de una clase estática, pero sí la clase singleton.

Sanjay Dwivedi
fuente
¿De qué sirve pasar un singleton a un método si siempre hay uno solo y ese siempre tiene una referencia estática?
Aaron Franke
3

Distinción de la clase estática.

JDK tiene ejemplos de singleton y static, por un lado java.lang.Mathes una clase final con métodos estáticos, por otro ladojava.lang.Runtime es una clase singleton.

Ventajas de singleton

  • Si su necesidad de mantener el estado que el patrón singleton es una mejor opción que la clase estática, porque mantener el estado en la clase estática conduce a errores, especialmente en entornos concurrentes, que podrían conducir a condiciones de carrera sin la sincronización adecuada de modificaciones paralelas por múltiples hilos.

  • La clase Singleton puede cargarse lentamente si es un objeto pesado, pero la clase estática no tiene tales ventajas y siempre se carga con entusiasmo.

  • Con Singleton, puede usar la herencia y el polimorfismo para extender una clase base, implementar una interfaz y proporcionar diferentes implementaciones.

  • Como los métodos estáticos en Java no se pueden anular, conducen a la inflexibilidad. Por otro lado, puede anular los métodos definidos en la clase singleton extendiéndolo.

Desventajas de la clase estática.

  • Es más fácil escribir pruebas unitarias para singleton que para la clase estática, porque puede pasar un objeto simulado cuando se espera singleton.

Ventajas de la clase estática.

  • La clase estática proporciona un mejor rendimiento que el singleton, porque los métodos estáticos están unidos en tiempo de compilación.

Hay varias realizaciones del patrón singleton, cada una con ventajas y desventajas.

  • Ansioso por cargar singleton
  • Singleton de bloqueo doblemente verificado
  • Idioma del titular de inicialización a pedido
  • El singleton basado en enumeración

Descripción detallada de cada uno de ellos es demasiado detallado, así que solo pongo un enlace a un buen artículo: todo lo que quieres saber sobre Singleton

Oleg Poltoratskii
fuente
2

Hay una gran diferencia entre una única instancia de clase estática (es decir, una sola instancia de una clase, que resulta ser una variable estática o global) y un solo puntero estático a una instancia de la clase en el montón:

Cuando su aplicación salga, se llamará al destructor de la instancia de clase estática. Eso significa que si usó esa instancia estática como singleton, su singleton dejó de funcionar correctamente. Si todavía hay código en ejecución que usa ese singleton, por ejemplo en un hilo diferente, es probable que ese código se bloquee.

gnasher729
fuente
1
Entonces, si la aplicación se cierra, ¿quedará Singleton en la memoria?
nanosoft
Creo que te refieres a cuando sale tu hilo actual, no a la aplicación, ¿verdad? Si la aplicación se cierra, no hay forma de que otro hilo use algo de ella.
Tom Brito
2

La diferencia en mi cabeza es implementar programación orientada a objetos (Singleton / Prototype) o programación funcional (Estática).

Estamos demasiado enfocados en la cantidad de objetos creados por el patrón singleton cuando lo que debemos enfocar es que al final sostenemos un objeto. Como otros ya han dicho, se puede extender, pasar como parámetro, pero lo más importante es que está lleno de estado.

Por otro lado, la estática se usa para implementar la programación funcional. Los miembros estáticos pertenecen a una clase. Son apátridas.

Por cierto, ¿sabías que puedes crear clases estáticas singleton :)

Atif Karbelkar
fuente
¿Cuál es el punto de pasar un singleton como parámetro ya que siempre tiene una referencia estática en la clase?
Aaron Franke