Envié una solicitud que escribí a otros arquitectos para la revisión del código. Uno de ellos casi inmediatamente me respondió y dijo "No use" estático ". No puede escribir pruebas automatizadas con clases y métodos estáticos." Debe evitarse "estático".
Revisé y 1/4 de mis clases están marcadas como "estáticas". Utilizo static cuando no voy a crear una instancia de una clase porque la clase es una clase global única utilizada en todo el código.
Luego mencionó algo relacionado con la burla, las técnicas IOC / DI que no se pueden usar con código estático. Él dice que es desafortunado cuando las bibliotecas de terceros son estáticas debido a su imposibilidad de prueba.
¿Es este otro arquitecto correcto?
actualización: aquí hay un ejemplo:
APIManager: esta clase mantiene diccionarios de API de terceros a los que llamo junto con el próximo tiempo permitido. Aplica los límites de uso de API que muchos terceros tienen en sus términos de servicio. Lo uso en cualquier lugar donde llamo a un servicio de terceros llamando a Thread.Sleep (APIManager.GetWait ("ProviderXYZ")); antes de hacer la llamada. Todo aquí es seguro para subprocesos y funciona muy bien con el TPL en C #.
fuente
static
está bien;static
los campos deben ser tratados con mucho cuidadoRespuestas:
Depende de si las clases estáticas mantienen el estado o no. Personalmente, no tengo ningún problema con las funciones sin estado agrupadas en una clase estática.
fuente
Él es demasiado general al respecto. Tiene razón, dificulta las pruebas. Sin embargo, las
static
clases y los métodos tienen su lugar y realmente depende del contexto. Sin ejemplos de código, realmente no se puede saber.Esto puede ser un fuerte olor a código. ¿Para qué estás usando las clases? Para mantener los datos? Para acceder a una base de datos? Entonces él está en lo correcto. Debería buscar la inyección de dependencia en ese caso, ya que tal clase estática es efectivamente un singleton implícito.
Si los está utilizando para métodos de extensión o ayudantes que no cambian el estado y solo operan con los parámetros que proporciona, generalmente están bien.
fuente
Lo mejor que puedes hacer es probar y hacer una prueba unitaria de tu código. Intente diseñar pruebas que sean repetibles, independientes, simples y pruebe solo un método a la vez. Intente ejecutar sus pruebas en un orden aleatorio diferente. ¿Se puede obtener una construcción "verde" estable?
En caso afirmativo, ese es un punto válido para defender su código. Sin embargo, si tiene dificultades, entonces tal vez debería optar por métodos basados en instancias.
fuente
Las respuestas ya publicadas cubren muchos puntos realmente buenos, pero hay uno que parece faltar:
Los campos estáticos nunca son basura recolectada.
Esto es realmente importante si tiene una aplicación con muchas restricciones de memoria, y este patrón puede ser muy común cuando las personas intentan implementar un caché.
Las funciones estáticas no son tan malas, pero todos los demás ya lo han cubierto con suficiente detalle.
fuente
Una de las ventajas que obtiene de IoC / DI es que la mayoría de las interacciones entre clases se negocian entre interfaces. Esto facilita la prueba de la unidad porque las interfaces se pueden burlar automática o semiautomáticamente y, por lo tanto, cada una de las partes se puede probar para entradas y salidas. Además, más allá de la capacidad de prueba, poner interfaces entre todo le permite tener el código más modular posible: puede reemplazar fácilmente una implementación sin preocuparse tanto de que esté arruinando dependencias.
Debido a que C # no tiene metaclases, una clase no puede implementar una interfaz usando características estáticas, por lo que las características estáticas de las clases terminan arruinando cualquier esfuerzo para implementar un modelo de objeto IoC / DI puro. Es decir, no puedes crear un simulacro para probarlos, y tienes que crear dependencias reales.
Si su empresa / proyecto invierte mucho en hacer IoC, esto, por supuesto, es una preocupación razonable, y el dolor que atraviesa es por el beneficio de todos. Sin embargo, desde un punto de vista arquitectónico, personalmente no creo que se deba seguir ningún modelo hasta la tumba. Hay algunas cosas que tienen sentido implementar usando métodos estáticos, por ejemplo, la estrategia de diseño singleton. Yo mismo estoy menos inclinado a las clases estáticas porque creo que tienden a perder las ventajas de OO, pero a veces una clase de biblioteca es probablemente una expresión más natural de algo que un motor.
El comentarista me recuerda los métodos de extensión, que por supuesto tienen que estar en clases estáticas en C #. Eso es legítimo, y es un ejemplo de cómo IoC puro no funciona muy bien en C #, al menos si está tratando de aprovechar la amplitud del lenguaje.
fuente
Las clases estáticas a veces se usan mal y deben ser:
También podría ser una función llamada 'utilidad' y parte de una clase de utilidad. Las clases de utilidad son clases que contienen solo métodos estáticos y sirven como funciones auxiliares sin ningún contexto.
fuente
Los métodos estáticos están bien para usar y tienen un lugar legítimo en la programación. Parece que su arquitecto tiene un marco de prueba que no es totalmente compatible con los métodos estáticos. Si su código es parte de un proyecto más grande, entonces es importante cumplir con las pautas de los arquitectos. Sin embargo, no permita que este proyecto le impida utilizar métodos estáticos cuando sea apropiado.
fuente
He estado usando propiedades estáticas para cosas que son comunes a todas las instancias de una clase. Y he estado usando métodos estáticos para obtener grupos de objetos de clase. De ninguna manera soy un experto, pero esto me ha funcionado hasta ahora.
Ejemplo de PHP:
fuente
Diré que los principios que tienen están bien, pero la declaración (no use estadísticas) puede estar equivocada. ¿Cuánto cuesta su código de cobertura? Si el número es alto y se siente cómodo con la prueba unitaria de su aplicación, entonces está bien. Si no, entonces sugeriría revisar el código. Puede encontrar que las clases estáticas son la razón o no, dependerá de muchas cosas.
fuente
Las clases con métodos estáticos abusan de los principios de OOP. Ya no es una OOP, es COP - programación orientada a clases.
Raramente tienen una clara "personalidad" (uso mi metáfora humana favorita aquí), o identidad. Entonces no saben quiénes son. Este punto solo es suficiente para deshacerse de este concepto en OOP, pero hay más de ellos.
El siguiente es una consecuencia del primer punto. Como esas clases no saben quiénes son, tienden a ser de grandes a enormes.
El tercero hace que su código sea absolutamente no mantenible. El uso de métodos estáticos introduce dependencias ocultas . Aparecen por todas partes, y nunca se sabe lo que está sucediendo en su clase. No puede estar seguro de eso solo mirando la firma del constructor.
Lentamente, pero inevitablemente, su código se vuelve cada vez menos cohesivo, ya que las dependencias ocultas están mal controladas. Parecen invisibles ¡Y es tan fácil agregar otro! No tiene que modificar la firma de ningún método. Todo lo que tienes que hacer es llamar a un método estático. Y qué código feo sigue ...
Ok, probablemente ya lo has adivinado. El acoplamiento apretado es a menudo un acompañante de baja cohesión. Si hay muchos clientes que usan alguna clase, entonces el acoplamiento se está haciendo más estricto. Y hay una gran seducción al usar una clase o método ya escrito que requiere solo una pequeña solución. Solo un método flag-parameter.
¿Qué usar en lugar de métodos estáticos? Bueno, mi sugerencia es OOP. ¿Por qué no intentarlo?
fuente