Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

Esto es lo que MSDN tiene que decir en Cuándo usar clases estáticas :

static class CompanyInfo
{
    public static string GetCompanyName() { return "CompanyName"; }
    public static string GetCompanyAddress() { return "CompanyAddress"; }
    //...
}
     

Usa una clase estática como una unidad de   organización para métodos no   asociado a objetos particulares.   Además, una clase estática puede hacer que tu   Implementación más sencilla y rápida.   Porque no tienes que crear un   Objeto para llamar a sus métodos.   Es útil organizar los métodos.   dentro de la clase de una manera significativa,   tales como los métodos de la clase de matemáticas   en el espacio de nombres del sistema.

Para mí, ese ejemplo no parece abarcar muchos posibles escenarios de uso para clases estáticas. En el pasado, he usado clases estáticas para conjuntos sin estado de funciones relacionadas, pero eso es todo. Entonces, ¿bajo qué circunstancias debería (y no debería) declararse estática una clase?

¿Fue útil?

Solución

Escribí mis pensamientos sobre clases estáticas en una respuesta anterior de Desbordamiento de pila: Clase con método único: ¿el mejor enfoque?

Solía ??amar las clases de utilidad llenas de métodos estáticos. Hicieron una gran consolidación de los métodos de ayuda que de otra forma estarían causando redundancia y un infierno de mantenimiento. Son muy fáciles de usar, no tienen instancias, no se eliminan, solo hay que disparar y olvidar. Supongo que este fue mi primer intento involuntario de crear una arquitectura orientada a servicios: muchos servicios sin estado que hicieron su trabajo y nada más. Sin embargo, a medida que un sistema crece, los dragones se acercan.

Polimorfismo

Supongamos que tenemos el método UtilityClass.SomeMethod que felizmente zumba. De repente necesitamos cambiar la funcionalidad ligeramente. La mayor parte de la funcionalidad es la misma, pero todavía tenemos que cambiar un par de partes. Si no hubiera sido un método estático, podríamos crear una clase derivada y cambiar el contenido del método según sea necesario. Como es un método estático, no podemos. Claro, si solo necesitamos agregar una funcionalidad antes o después del método anterior, podemos crear una nueva clase y llamar a la anterior dentro de él, pero eso es muy grave.

Problemas de interfaz

Los métodos estáticos no se pueden definir a través de interfaces por razones lógicas. Y como no podemos anular los métodos estáticos, las clases estáticas son inútiles cuando necesitamos pasarlas por su interfaz. Esto nos hace incapaces de usar clases estáticas como parte de un patrón de estrategia. Podríamos solucionar algunos problemas con pasando delegados en lugar de interfaces .

Pruebas

Esto básicamente va de la mano con los problemas de interfaz mencionados anteriormente. Como nuestra capacidad para intercambiar implementaciones es muy limitada, también tendremos problemas para reemplazar el código de producción con el código de prueba. Nuevamente, podemos envolverlos, pero requerimos que cambiemos grandes partes de nuestro código para poder aceptar envoltorios en lugar de los objetos reales.

Fomenta blobs

Como los métodos estáticos generalmente se usan como métodos de utilidad y los métodos de utilidad generalmente tienen propósitos diferentes, terminaremos rápidamente con una clase grande llena de funcionalidad no coherente; idealmente, cada clase debe tener un solo propósito dentro del sistema. Preferiría tener cinco veces más clases, siempre que sus propósitos estén bien definidos.

Corrección de parámetros

Para empezar, ese pequeño método estático e inocente podría tomar un solo parámetro. A medida que la funcionalidad crece, se agregan un par de nuevos parámetros. Pronto se agregan otros parámetros que son opcionales, por lo que creamos sobrecargas del método (o simplemente agregamos valores predeterminados, en los idiomas que los admiten). En poco tiempo, tenemos un método que toma 10 parámetros. Solo los tres primeros son realmente necesarios, los parámetros 4-7 son opcionales. Pero si se especifica el parámetro 6, también se debe completar 7-9 ... Si hubiéramos creado una clase con el único propósito de hacer lo que hizo este método estático, podríamos resolverlo tomando los parámetros requeridos en el constructor, y permitir que el usuario establezca valores opcionales a través de propiedades, o métodos para establecer múltiples valores interdependientes al mismo tiempo. Además, si un método ha crecido a esta cantidad de complejidad, es muy probable que tenga que estar en su propia clase de todos modos.

Exigir a los consumidores que creen una instancia de clases sin ningún motivo

Uno de los argumentos más comunes es: ¿por qué exigir que los consumidores de nuestra clase creen una instancia para invocar este método único, mientras que después no tienen ningún uso para la instancia? Crear una instancia de una clase es una operación muy barata en la mayoría de los idiomas, por lo que la velocidad no es un problema. Agregar una línea de código adicional al consumidor es un bajo costo para sentar las bases de una solución mucho más fácil de mantener en el futuro. Y, por último, si desea evitar la creación de instancias, simplemente cree un envoltorio singleton de su clase que permita una reutilización fácil, aunque esto hace que el requisito de que su clase sea sin estado. Si no es sin estado, aún puede crear métodos de envoltura estática que manejen todo, mientras que a la vez le ofrece todos los beneficios. Por último, también puede crear una clase que oculte la creación de instancias como si fuera un singleton: MyWrapper.Instance es una propiedad que solo devuelve new MyClass ();

Solo un Sith trata en absolutos

Por supuesto, hay excepciones a mi aversión a los métodos estáticos. Las verdaderas clases de utilidad que no suponen ningún riesgo de hincharse son casos excelentes para métodos estáticos: System.Convert como ejemplo. Si su proyecto es único y no requiere ningún mantenimiento futuro, la arquitectura general realmente no es muy importante (estática o no estática, no importa), sin embargo, la velocidad de desarrollo sí lo hace.

Estándares, estándares, estándares!

El uso de métodos de instancia no le impide utilizar también métodos estáticos, y viceversa. Mientras exista un razonamiento detrás de la diferenciación y se estandarice. No hay nada peor que mirar una capa de negocios en expansión con diferentes métodos de implementación.

Otros consejos

Al decidir si hacer una clase estática o no estática, debe ver qué información está tratando de representar. Esto conlleva un estilo de programación más ' de abajo hacia arriba ' donde te concentras primero en los datos que estás representando. ¿Es la clase en la que estás escribiendo un objeto del mundo real como una roca o una silla? Estas cosas son físicas y tienen atributos físicos como el color y el peso que le indican que es posible que desee crear una instancia de múltiples objetos con diferentes propiedades. Puede que quiera una silla negra Y una silla roja al mismo tiempo. Si alguna vez necesita dos configuraciones al mismo tiempo, sabrá al instante que querrá crear una instancia como un objeto para que cada objeto pueda ser único y exista al mismo tiempo.

En el otro extremo, las funciones estáticas tienden a prestar más a acciones que no pertenecen a un objeto del mundo real o un objeto que puede representar fácilmente. Recuerde que los predecesores de C # son C ++ y C, donde puede definir funciones globales que no existen en una clase. Esto se presta más a la programación ' de arriba hacia abajo '. Se pueden usar métodos estáticos para estos casos en los que no tiene sentido que un 'objeto' realice la tarea. Al obligarte a usar clases, esto hace que sea más fácil agrupar la funcionalidad relacionada que te ayuda a crear un código más mantenible.

La mayoría de las clases se pueden representar ya sea estáticas o no estáticas, pero cuando tenga dudas, simplemente vuelva a sus raíces OOP e intente pensar en lo que está representando. Es este un objeto que está realizando una acción (un automóvil que puede acelerar, ralentizar, girar) o algo más abstracto (como mostrar la salida).

Póngase en contacto con su OOP interno y nunca podrá salir mal.

Para C # 3.0, los métodos de extensión solo pueden existir en clases estáticas de nivel superior.

Si utiliza herramientas de análisis de código (por ejemplo, FxCop ), le recomendamos que marque un método static si ese método no accede a los datos de instancia. La razón es que hay una ganancia de rendimiento. MSDN: CA1822: marcar miembros como estáticos .

En realidad, es más una directriz que una regla ...

Tiendo a usar clases estáticas para fábricas. Por ejemplo, esta es la clase de registro en uno de mis proyectos:

public static class Log
{
   private static readonly ILoggerFactory _loggerFactory =
      IoC.Resolve<ILoggerFactory>();

   public static ILogger For<T>(T instance)
   {
      return For(typeof(T));
   }

   public static ILogger For(Type type)
   {
      return _loggerFactory.GetLoggerFor(type);
   }
}

Puede que incluso hayas notado que IoC se llama con un acceso estático. La mayoría del tiempo para mí, si puede llamar a métodos estáticos en una clase, eso es todo lo que puede hacer, así que marque la clase como estática para mayor claridad.

Las clases estáticas son muy útiles y tienen un lugar, por ejemplo bibliotecas.

El mejor ejemplo que puedo proporcionar es la clase .Net Math, una clase estática de espacio de nombres del Sistema que contiene una biblioteca de funciones matemáticas.

Es como cualquier otra cosa, use la herramienta adecuada para el trabajo y, si no, se puede abusar de cualquier cosa.

Descartar en blanco las clases estáticas como incorrectas, no usarlas o decir "solo puede haber una" o ninguno, es tan incorrecto como sobre el uso de ellos.

C # .Net contiene varias clases estáticas que se usan igual que la clase de matemáticas.

Entonces, dada la implementación correcta, son tremendamente útiles.

Tenemos una clase de Zona horaria estática que contiene una serie de funciones de zona horaria relacionadas con el negocio, no hay necesidad de crear múltiples instancias de la clase tanto como la clase Matemática que contiene un conjunto de funciones (métodos) relacionadas con Zona horaria globalmente accesibles en una clase estática.

Comencé a usar clases estáticas cuando deseo usar funciones, en lugar de clases, como mi unidad de reutilización. Anteriormente, estaba todo sobre el mal de las clases estáticas. Sin embargo, aprender F # me ha hecho verlos desde una nueva perspectiva.

¿Qué quiero decir con esto? Bueno, digamos que al elaborar un código super DRY , termino con un montón de uno clases de metodo Puedo simplemente jalar estos métodos a una clase estática y luego inyectarlos en dependencias usando un delegado. Esto también funciona bien con mi inyección de dependencia (DI) contenedor de elección Autofac.

Por supuesto, tomar una dependencia directa de un método estático sigue siendo generalmente malvado (hay algunos usos no malvados).

Utilizo clases estáticas como un medio para definir " funcionalidad adicional " que un objeto de un tipo dado podría usar en un contexto específico. Por lo general, resultan ser clases de utilidad.

Aparte de eso, creo que " Usa una clase estática como una unidad de organización para métodos no asociados con objetos particulares. " describe bastante bien su uso previsto.

Esta es otra pregunta antigua pero muy interesante desde que OOP se activó. Hay muchas razones para usar (o no) una clase estática, por supuesto y la mayoría de ellas se han cubierto en la multitud de respuestas.

Solo agregaré mis 2 centavos a esto, diciendo que, hago una clase estática, cuando esta clase es algo que sería único en el sistema y que realmente no tendría sentido tener ninguna instancia en el programa. . Sin embargo, reservo este uso para grandes clases. Nunca declaro clases tan pequeñas como en el ejemplo de MSDN como " static " y, ciertamente, no las clases que van a ser miembros de otras clases.

También me gusta señalar que los métodos estáticos y las clases estáticas son dos cosas diferentes a considerar. Las principales desventajas mencionadas en la respuesta aceptada son los métodos estáticos. las clases estáticas ofrecen la misma flexibilidad que las clases normales (en lo que respecta a las propiedades y los parámetros), y todos los métodos utilizados en ellas deben ser relevantes para el propósito de la existencia de la clase.

Un buen ejemplo, en mi opinión, de un candidato para una clase estática es un " FileProcessing " Clase, que contendría todos los métodos y propiedades relevantes para que los diversos objetos del programa realicen operaciones complejas de procesamiento de archivos. Difícilmente tiene algún significado tener más de una instancia de esta clase y ser estático hará que esté disponible para todo lo que esté en tu programa.

Solo uso clases estáticas para métodos de ayuda, pero con el advenimiento de C # 3.0, prefiero usar métodos de extensión para esos.

Raramente uso los métodos de clases estáticas por las mismas razones por las que rara vez uso el patrón de diseño " singleton " ;.

Basado en MSDN :

  1. No puede crear la instancia para clases estáticas
  2. Si la clase declarada como estática, la variable miembro debe ser estática para esa clase
  3. Sellado [No se puede heredar]
  4. No puede contener el constructor de instancia
  5. Gestión de memoria

Ejemplo: los cálculos matemáticos (valores matemáticos) no cambian [CÁLCULO ESTÁNDAR PARA VALORES DEFINIDOS]

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top