Haciendo métodos todos estáticos en clase

Un colega me dijo que, según una de mis clases (es una clase de instancia), que si no tiene campos en su clase (campos de respaldo), simplemente haga que todos los métodos sean estáticos en la clase o convierta la clase en un singleton para no tiene que usar la palabra clave new para los métodos de llamada en esta clase BL.

Supongo que esto es común y una buena práctica? OOP básico? Solo quiero ver la opinión de la gente sobre eso.

Creo que básicamente lo dice, ya que no hay estado, no hay necesidad de que los métodos sean métodos de instancia.

No estoy seguro de que sea un singleton cada vez como una opción en este caso … ¿es algún tipo de patrón o buen consejo que me está dando?

Aquí está la clase de la que estoy hablando (por favor, no vuelva a publicar nada de este código en este hilo, esto es privado): http://www.elbalazo.net/post/class.txt

Hay muy poco inconveniente en llamar a un nuevo y construir una referencia de clase, especialmente si la clase no tiene estado. Las asignaciones son rápidas en .NET, por lo que no usaría esto solo como una justificación para que una clase sea estática.

Por lo general, creo que una clase debería estar estática si la clase no tiene un contexto específico; si está usando la clase simplemente como un marcador de posición para los métodos de “utilidad” o las operaciones no específicas del contexto, entonces tiene sentido que sea una clase estática. .

Si esa clase tiene una necesidad específica de contexto y un significado en un sentido concreto, entonces probablemente no justifique ser estático, incluso si no tiene un estado (aunque esto es raro). Hay momentos en que el propósito de la clase se define por su propia referencia, que proporciona un “estado” de un tipo (la referencia en sí) sin ninguna variable local.

Dicho esto, hay una gran diferencia entre una clase estática y un singleton. Un singleton es un animal diferente: desea utilizarlo cuando necesite una instancia, pero solo una instancia, de la clase que se creará. Hay un estado en un singleton, pero está utilizando este patrón para imponer que solo hay una única copia del estado. Esto tiene un significado muy diferente, y recomendaría encarecidamente evitar el uso de un singleton solo para evitar la necesidad de “llamar a un nuevo”.

No hay una regla absoluta para cuando una clase debe ser estática. Puede que no tenga estado, pero puede que lo necesite para la igualdad de referencia o el locking. Las clases deben ser estáticas cuando su propósito se ajusta a ser implementado como una clase estática. No debes seguir reglas estrictas en estas situaciones; Usar lo que ‘sientes’ es correcto.

No tener estado lo hace candidato para la estática, pero mire para qué se usa antes de refactorizarlo arbitrariamente.

La falta de estado solo no es razón para hacer que los métodos sean estáticos. Hay muchos casos en los que una clase sin estado todavía debería tener métodos de instancia. Por ejemplo, cada vez que necesite pasar implementaciones específicas de alguna lógica entre rutinas, es mucho más fácil hacerlo con clases que tienen métodos de instancia, ya que nos permite usar interfaces:

interface IConnectionProvider { object GetConnectedObject(); } 

Podríamos tener una docena de implementaciones de lo anterior y pasarlas a rutinas que requieran un IConnectionProvider . En ese caso, la estática es una alternativa muy torpe.

No hay nada de malo en tener que usar new para usar un método en una clase sin estado.

Siempre que no necesite crear ninguna abstracción de su clase, los métodos estáticos están bien. Si su clase necesita ser burlada o implementar cualquier tipo de interfaz, entonces es mejor que la clase sea un singleton, ya que no puede simular métodos estáticos en las clases. Puede hacer que un singleton implemente una interfaz y puede heredar métodos de instancia de un singleton, mientras que no puede heredar métodos estáticos.

En general, usamos métodos singleton en lugar de métodos estáticos para permitir que nuestras clases se abstraigan fácilmente. Esto ha ayudado en las pruebas unitarias muchas veces, ya que nos hemos topado con escenarios en los que queríamos burlarnos de algo y podríamos hacerlo fácilmente ya que el comportamiento se implementó como métodos de instancia en un singleton.

Las clases de utilidad a menudo se componen de métodos independientes que no necesitan estado. En ese caso, es una buena práctica hacer que esos métodos sean estáticos. También puede hacer que la clase sea estática, por lo que no se puede crear una instancia.

Con C # 3, también puede aprovechar los métodos de extensión, que extenderán otras clases con esos métodos. Tenga en cuenta que en ese caso, se requiere la clase estática.

 public static class MathUtil { public static float Clamp(this float value, float min, float max) { return Math.Min(max, Math.Max(min, value)); } } 

Uso:

 float f = ...; f.Clamp(0,1); 

Puedo pensar en muchas razones para una clase no estática sin miembros. Por un lado, puede implementar una interfaz y proporcionar / boost el comportamiento de otro. Para dos, puede tener métodos virtuales o abstractos que permitan la personalización. Básicamente, el uso de métodos ‘estáticos’ es lo peor de la progtwigción de procedimientos y es contrario al diseño orientado a objetos.

Dicho esto, las rutinas a menudo de pequeñas utilidades se realizan mejor con una implementación de procedimiento, así que no se asuste si tiene sentido. Considere String.IsNullOrEmpty () un gran ejemplo de una rutina estática de procedimiento que proporciona beneficios al no ser un método. (el beneficio es que también puede verificar si la cadena es nula)

Otro ejemplo en el otro lado de la cerca sería una rutina de serialización. No necesita ningún miembro por decir. Supongamos que tiene dos métodos Escribir (Secuencia, Objeto) y Objeto Leer (Secuencia). No es necesario que este sea un objeto y que los métodos estáticos podrían ser suficientes; Sin embargo, tiene sentido ser un objeto o una interfaz. Como un objeto, podría anular su comportamiento o, más tarde, cambiar su implementación para que almacene en caché la información sobre los tipos de objetos que serializa. Al convertirlo en un objeto para empezar, no te limites.

La mayoría de las veces está bien hacer que la clase sea estática. Pero una pregunta mejor es ¿por qué tienes una clase sin estado?

Hay casos muy raros en los que una clase sin estado es un buen diseño. Pero las clases sin estado rompen el diseño orientado a objetos. Por lo general, son un retroceso a la descomposición funcional (toda la rabia antes de que las técnicas orientadas a objetos se hicieran populares). Antes de hacer una clase estática, pregúntese si los datos en los que está trabajando deberían incluirse en la clase o si todas las funciones de la clase de utilidad no deberían dividirse entre otras clases que pueden o no existir.

Asegúrese de tener una buena razón para hacer que la clase sea estática.

Según las pautas de diseño del marco:

Las clases estáticas se deben usar solo como clases de apoyo para el núcleo orientado a objetos del marco.

NO trate las clases estáticas como un cubo misceláneo.

Debe haber una carta clara para la clase.

Clase estática, métodos estáticos y clase Singleton son tres conceptos diferentes. Las clases estáticas y los métodos estáticos se usan generalmente para implementar clases estrictamente de utilidad o hacerlas sin estado y, por lo tanto, seguras para subprocesos y de forma simultánea.

Las clases estáticas no necesitan ser Singletons. Singleton significa que solo hay una instancia de una clase, que de otra manera es instanciable. Se utiliza con mayor frecuencia para encapsular la representación del mundo físico de una instancia verdaderamente única de un recurso, como un solo conjunto de bases de datos o una sola impresora.

Volviendo a la sugerencia de su colega, tiendo a aceptar que es un buen consejo. No es necesario crear una instancia de una clase si los métodos se vuelven estáticos, cuando pueden ser estáticos. Hace que el código de la persona que llama sea más legible y que los métodos llamados sean más fáciles de usar.

Parece que estás hablando de una clase estrictamente de utilidad, en cuyo caso realmente no hay razón para tener instancias separadas.

Hacer esos métodos de utilidad estáticos. Puede mantener la clase como un objeto regular si lo desea (para permitir la futura adición de métodos de instancia / información de estado).