En C # Los métodos estáticos han tenido un propósito que nos permite llamarlos sin instanciar clases. Solo en el último año nos hemos vuelto más conscientes de los problemas de usar clases y métodos estáticos.
- No pueden usar interfaces
- No pueden usar la herencia
- Son difíciles de probar porque no puedes hacer burlas y talones
¿Hay una mejor manera? Obviamente, debemos poder acceder a los métodos de la biblioteca sin clases de instancias todo el tiempo, de lo contrario nuestro código se volvería bastante abarrotado
Una posible solución es usar una nueva palabra clave para un concepto antiguo: the singleton . Los Singleton son instancias globales de una clase, ya que son instancias que podemos usar como lo haríamos con las clases normales. Sin embargo, para hacer su uso agradable y práctico, necesitaríamos un poco de azúcar sintáctica.
Diga que la clase de Matemáticas sería de tipo singleton en lugar de una clase real. La clase real que contiene todos los métodos predeterminados para el singleton matemático es DefaultMath, que implementa la interfaz IMath. El singleton se declararía como
singleton Math : IMath
{
public Math
{
this = new DefaultMath();
}
}
Si quisiéramos sustituir nuestra propia clase para todas las operaciones matemáticas, podríamos crear una nueva clase
MyMath que hereda DefaultMath , o simplemente podemos heredar de la interfaz IMath y crear una Clase completamente nueva. Para hacer que nuestra clase sea la clase de Matemáticas activa, harías una tarea simple
Math = new MyMath();
y voilá! La próxima vez que llamemos a Math.Floor llamará a tu método. Tenga en cuenta que para un singleton normal tendríamos que escribir algo como Math.Instance.Floor pero el compilador elimina la necesidad de la propiedad Instance
Otra idea sería poder definir un singleton como perezoso para que se ejemplifiquen solo cuando se les llama por primera vez, como
lazy singleton Math : IMath
¿Qué crees que hubiera sido una mejor solución que las clases y los métodos estáticos? ¿Hay algún problema con este enfoque?
Addendum
Se han planteado algunos puntos, que uno de los principales beneficios de los métodos estáticos es tener métodos que son "sin estado" y, por lo tanto, libres de efectos secundarios, en cierta medida, desde el punto de vista de la concurrencia. Estoy totalmente de acuerdo en que ese es un punto válido. Sin embargo, estamos mezclando dos problemas y problemas diferentes aquí: uno es hacer que algunos métodos sean invocables y accesibles globalmente sin tener que crear explícitamente una instancia. El otro es tener métodos que son apátridas.
El segundo problema podría resolverse con un método que tenga algo así como una palabra clave sin estado que, de manera similar a la estática, les impidiera llamar a esto o quizás incluso más para no aplicar efectos secundarios. Con singletons en lugar de clases estáticas y algo así como clases y métodos sin estado, creo que tendrías los siguientes pros y contras
Pro's
- Métodos "estáticos" en otras clases y clases marco podrían fácilmente ser diseñado para ser anulable
- Las clases serían más fáciles de probar
- Usar instancias en lugar de clases estáticas significa que los patrones de diseño funcionan mejor (cosas como fábricas)
- Sin limitación de herencia y polimorfismo en contraste con la estática
Cons
- ¿Quizás un rendimiento ligeramente peor?
- Los programadores malos lo harán, pero todo en Singletons para tenerlos accesibles globalmente en lugar de usar la inyección de dependencia, tal vez solo debería poder acceder a los métodos de Singleton y no a propiedades / campos para evitar variables globales :)
- ?
Tal vez Math fue un mal ejemplo, pero imagina que si los métodos de cadena .Net fueran ineficientes, podrías reemplazarlos fácilmente con los tuyos usando este método. O alguna clase de terceros tiene un método de singleton que quisieras alterar ligeramente, podrías heredar y alterar ese método