¿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?
design-patterns
static
singleton
Jorge Córdoba
fuente
fuente
getInstance()
método cada vez que quiera usarlo (aunque probablemente en la mayoría de los casos no importa ).singleton
objeto donde losstatic
métodos son solo funciones, una entidad no OO.Respuestas:
¿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.
fuente
Foo
y tienes un método que tomaFoo
un 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.La verdadera respuesta es de Jon Skeet, en otro foro aquí .
fuente
interface
con una clase Singleton, pero los métodos estáticos de una clase (o, por ejemplo, un C #static class
) no pueden.fuente
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.
fuente
static
Las clases no son para nada que necesite estado. Es útil para poner un montón de funciones juntas, es decirMath
(oUtils
en proyectos). Entonces, el nombre de la clase solo nos da una pista donde podemos encontrar las funciones y nada más.Singleton
es mi patrón favorito y lo uso para administrar algo en un solo punto. Es más flexible que lasstatic
clases y puede mantener su estado. Puede implementar interfaces, heredar de otras clases y permitir la herencia.Mi regla para elegir entre
static
ysingleton
:Si hay un montón de funciones que deben mantenerse juntas, entonces
static
es la opción. Cualquier otra cosa que necesite acceso único a algunos recursos, podría implementarse como asingleton
.fuente
State
es la combinación de diferentes propiedades de un objeto que generalmente cambian con el tiempo. Puedes buscar en Google para una definición formal.Clase estática: -
No puede crear la instancia de la clase estática.
Cargado automáticamente por .NET Framework Common Language Runtime (CLR) cuando se carga el programa o el espacio de nombres que contiene la clase.
La clase estática no puede tener un constructor.
No podemos pasar la clase estática al método.
No podemos heredar la clase estática a otra clase estática en C #.
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)
Único:-
Puede crear una instancia del objeto y reutilizarlo.
La instancia de Singleton se crea por primera vez cuando el usuario lo solicitó.
La clase Singleton puede tener un constructor.
Puede crear el objeto de la clase singleton y pasarlo al método.
La clase Singleton no dice ninguna restricción de herencia.
Podemos disponer los objetos de una clase singleton pero no de clase estática.
Los métodos pueden ser anulados.
Se puede cargar lentamente cuando sea necesario (las clases estáticas siempre se cargan).
Podemos implementar la interfaz (la clase estática no puede implementar la interfaz).
fuente
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.
fuente
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:
fuente
Para ampliar la respuesta de Jon Skeet
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.
fuente
MySingleton mockOfMySingleton = mock(MySingleton.class)
.new ClazzToTest(mockSingleton);
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
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 )
único
En resumen, solo usaría clases estáticas para mantener métodos utilitarios y usar Singleton para todo lo demás.
Ediciones
las clases estáticas también están cargadas de forma diferida. Gracias @jmoreno (¿ Cuándo ocurre la inicialización de la clase estática? )
método oculto para clases estáticas. Gracias @ MaxPeng.
fuente
Animal animal = new Cat();
entoncesanimal.foo();
que pasa?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.
fuente
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.
fuente
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
SomeClass
esperaILogger
que se pase una instancia de implementación a su constructor.La clase Singleton es importante para que sea posible la inyección de dependencia.
fuente
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.
fuente
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.
fuente
Las principales diferencias son:
fuente
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:
Uso de getPrice:
Implementación final de Singleton:
clase de prueba:
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.
fuente
Estoy de acuerdo con esta definición:
Puede encontrar otras diferencias interesantes sobre: Patrón Singleton Versus Clase Estática
fuente
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.
fuente
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.
fuente
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 ..
fuente
fuente
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.
fuente
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.
fuente
Leí lo siguiente y creo que también tiene sentido:
del libro Proceso de pensamiento orientado a objetos 4ª ed.
fuente
En un artículo que escribí, describí mi punto de vista sobre por qué el singleton es mucho mejor que una clase estática:
fuente
Podemos crear el objeto de la clase singleton y pasarlo al método.
La clase Singleton no tiene ninguna restricción de herencia.
No podemos deshacernos de los objetos de una clase estática, pero sí la clase singleton.
fuente
Distinción de la clase estática.
JDK tiene ejemplos de singleton y static, por un lado
java.lang.Math
es 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.
Ventajas de la clase estática.
Hay varias realizaciones del patrón singleton, cada una con ventajas y desventajas.
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
fuente
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.
fuente
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 :)
fuente