Nombre las consideraciones de diseño al decidir entre el uso de un singleton o una clase estática. Al hacer esto, se ve obligado a contrastar los dos, por lo que cualquier contraste que se le ocurra también es útil para mostrar su proceso de pensamiento. Además, a todos los entrevistadores les gusta ver ejemplos ilustrativos. :)
design-patterns
cdleary
fuente
fuente
Respuestas:
fuente
¿Qué tal "evitar ambos"? Singletons y clases estáticas:
En su lugar, busque en la inyección de dependencia y la inversión de las bibliotecas de contenedores de control . Varias de las bibliotecas de IoC se encargarán de la gestión de por vida por usted.
(Como siempre, hay excepciones, como clases de matemáticas estáticas y métodos de extensión de C #).
fuente
Hide Dependencies
little sideinfo sobre este punto: puede implementar el patrón de inversión de control, por ejemplo, utilizando Ninject . Esto le permite usar solo una instancia de un tipo al vincularlo a aSingletonScope
, lo que significa que siempre inyectará la misma instancia, pero la clase no será singleton.Yo diría que la única diferencia es la sintaxis: MySingleton.Current.Whatever () vs MySingleton.Whatever (). El estado, como mencionó David, es en última instancia "estático" en cualquier caso.
EDITAR: La brigada de enterramiento vino de Digg ... de todos modos, pensé en un caso que requeriría un singleton. Las clases estáticas no pueden heredar de una clase base ni implementar una interfaz (al menos en .Net no pueden). Entonces, si necesita esta funcionalidad, debe usar un singleton.
fuente
Una de mis discusiones favoritas sobre este tema está aquí (sitio original caído, ahora vinculado a Internet Archive Wayback Machine ).
Para resumir las ventajas de flexibilidad de un Singleton:
fuente
Una clase estática con una carga de variables estáticas es un truco.
Un singleton con una instancia real es mejor.
El estado está SOLO en la instancia.
Por lo tanto, el singleton se puede modificar más tarde para hacer agrupaciones, instancias locales de subprocesos, etc. Y no es necesario cambiar nada del código ya escrito para obtener el beneficio.
Es posible hacer algo similar con una clase estática, pero habrá una sobrecarga por llamada en el envío indirecto.
Puede obtener la instancia y pasarla a una función como argumento. Esto permite que el código se dirija al singleton "correcto". Sabemos que solo necesitará uno ... hasta que no lo necesite.
El gran beneficio es que los singleton con estado se pueden convertir en seguros para subprocesos, mientras que una clase estática no, a menos que la modifique para que sea un singleton secreto.
fuente
Piense en un singleton como un servicio. Es un objeto que proporciona un conjunto específico de funciones. P.ej
La fábrica de objetos es un objeto que realiza un servicio específico.
Por el contrario, una clase llena de métodos estáticos es una colección de acciones que tal vez desee realizar, organizadas en un grupo relacionado (la clase). P.ej
El ejemplo de StringUtils aquí es una colección de funcionalidades que se pueden aplicar en cualquier lugar. El objeto singleton factory es un tipo específico de objeto con una clara responsabilidad que puede crearse y transmitirse donde sea necesario.
fuente
Las clases estáticas se instancian en tiempo de ejecución. Esto puede llevar mucho tiempo. Se pueden crear instancias de singletons solo cuando sea necesario.
fuente
Los singletons no deben usarse de la misma manera que las clases estáticas. En esencia,
es esencialmente lo mismo que
Lo que debería estar haciendo es tratar el singleton como un objeto más . Si un servicio requiere una instancia del tipo singleton, pase esa instancia en el constructor:
El servicio no debe ser consciente de que el objeto es un singleton y debe tratar el objeto como solo un objeto.
El objeto ciertamente se puede implementar, como un detalle de implementación y como un aspecto de la configuración general, como un singleton si eso facilita las cosas. Pero las cosas que usan el objeto no deberían tener que saber si el objeto es un singleton o no.
fuente
Si por "clase estática" te refieres a una clase que solo tiene variables estáticas, entonces realmente pueden mantener el estado. Tengo entendido que la única diferencia sería cómo accedes a esto. Por ejemplo:
versus
Los componentes internos de MySingleton obviamente serán diferentes entre ellos, pero, dejando de lado los problemas de seguridad de subprocesos, ambos funcionarán de la misma manera con respecto al código del cliente.
fuente
El patrón singleton se usa generalmente para dar servicio a datos estáticos o independientes de la instancia donde varios subprocesos pueden acceder a los datos al mismo tiempo. Un ejemplo pueden ser los códigos de estado.
fuente
Los singleton nunca deben usarse (a menos que considere una clase sin estado mutable como singleton). Las "clases estáticas" no deberían tener un estado mutable, salvo quizás las memorias caché seguras para subprocesos y similares.
Prácticamente cualquier ejemplo de singleton muestra cómo no hacerlo.
fuente
Si un singleton es algo de lo que puede deshacerse, para limpiarlo después, puede considerarlo cuando es un recurso limitado (es decir, solo 1) que no necesita todo el tiempo y tiene algún tipo de memoria o costo de los recursos cuando se asigna.
El código de limpieza se ve más natural cuando tiene un singleton, a diferencia de una clase estática que contiene campos de estado estáticos.
El código, sin embargo, lucirá similar de cualquier manera, así que si tienes razones más específicas para preguntar, quizás debas explicarlo.
fuente
Los dos pueden ser muy similares, pero recuerda que el verdadero Singleton tiene en sí una instancia (concedida, una vez) y luego se sirve. Una clase de base de datos PHP que devuelve una instancia de
mysqli
no es realmente un Singleton (como algunas personas lo llaman), porque está devolviendo una instancia de otra clase, no una instancia de la clase que tiene la instancia como miembro estático.Por lo tanto, si está escribiendo una nueva clase de la que planea permitir solo una instancia en su código, también puede escribirla como Singleton. Piense en ello como escribir una clase simple-jane y agregarla para facilitar el requisito de instanciación única. Si está usando la clase de otra persona que no puede modificar (como
mysqli
), debería usar una clase estática (incluso si no puede prefijar su definición con la palabra clave).fuente
Los singleton son más flexibles, lo que puede ser útil en los casos en que desee que el método Instance devuelva diferentes subclases concretas del tipo Singleton en función de algún contexto.
fuente
Las clases estáticas no se pueden pasar como argumentos; instancias de un singleton pueden ser. Como se mencionó en otras respuestas, esté atento a los problemas de subprocesos con clases estáticas.
rp
fuente
Un singleton puede tener un constructor y un destructor. Dependiendo de su idioma, el constructor puede llamarse automáticamente la primera vez que se usa su singleton, o nunca si su singleton no se usa en absoluto. Una clase estática no tendría tal inicialización automática.
Una vez que se obtiene una referencia a un objeto singleton, se puede usar como cualquier otro objeto. Es posible que el código del cliente ni siquiera necesite saber que está usando un singleton si una referencia al singleton se almacena anteriormente:
Obviamente, esto facilita las cosas cuando elige deshacerse del patrón Singleton en favor de un patrón real, como IoC.
fuente
Utilice el patrón singleton cuando necesite calcular algo en tiempo de ejecución que calcularía en tiempo de compilación si pudiera, como tablas de búsqueda.
fuente
Creo que un lugar donde Singleton tendrá más sentido que la clase estática es cuando tienes que construir un grupo de recursos costosos (como conexiones de bases de datos). No estaría interesado en crear el grupo si nadie los usa (la clase estática significa que usted hace el trabajo costoso cuando la clase está cargada).
fuente
Un singleton también es una buena idea si desea forzar un almacenamiento de datos en caché eficiente. por ejemplo, tengo una clase que busca definiciones en un documento xml. Dado que analizar el documento puede llevar un tiempo, configuro un caché de definiciones (utilizo SoftReferences para evitar outOfmemeoryErrors). Si la definición deseada no está en la caché, hago el costoso análisis xml. De lo contrario, devuelvo una copia del caché. Dado que tener múltiples cachés significaría que aún podría tener que cargar la misma definición varias veces, necesito tener un caché estático. Elijo implementar esta clase como singleton para poder escribir la clase usando solo miembros de datos normales (no estáticos). Esto me permite aún crear una diferenciación de la clase en caso de que la necesite por algún motivo (serialización, pruebas unitarias, etc.)
fuente
Singleton es como un servicio, como ya se mencionó. Pro es su flexibilidad. Estático, bueno, necesita algunas partes estáticas para implementar Singleton.
Singleton tiene un código para encargarse de la creación de instancias del objeto real, lo que puede ser de gran ayuda si tiene problemas con las carreras. En una solución estática, es posible que deba lidiar con problemas de carreras en múltiples ubicaciones de código.
Sin embargo, al igual que Singleton se puede construir con algunas variables estáticas, es posible que pueda compararlo con 'goto'. Puede ser muy útil para construir otras estructuras, pero realmente necesita saber cómo usarlo y no debe "abusar" de él. Por lo tanto, la recomendación general es ceñirse a Singleton y usar estática si es necesario.
también verifique la otra publicación: ¿Por qué elegir una clase estática en lugar de una implementación singleton?
fuente
referir esto
resumen:
a. Una regla general fácil que puede seguir es que si no necesita mantener el estado, puede usar una clase estática; de lo contrario, debe usar un Singleton.
segundo. use un Singleton si es un objeto particularmente "pesado". Si su objeto es grande y ocupa una cantidad razonable de memoria, muchas llamadas n / w (grupo de conexiones) ..etc. Para asegurarse de que no se instanciará varias veces. Una clase Singleton ayudará a evitar que este caso suceda.
fuente
Cuando la clase única necesita estado. Los singleton mantienen un estado global, las clases estáticas no.
Por ejemplo, crear un ayudante para una clase de registro: si tiene una colmena modificable (usuario actual de HKey frente a máquina local de HKEY), puede ir:
Ahora, cualquier otra llamada a ese singleton operará en la colmena de la máquina local. De lo contrario, utilizando una clase estática, tendría que especificar esa colmena de máquina local en cada momento, o tener un método como
ReadSubkeyFromLocalMachine
.fuente