¿No usa "Static" en C #?

104

Envié una solicitud que escribí a otros arquitectos para revisar el código. Uno de ellos me contestó casi de inmediato y me dijo: "No use" estático ". No puede escribir pruebas automáticas con clases y métodos estáticos." Estático "debe evitarse".

Lo verifiqué y 1/4 de mis clases están marcadas como "estáticas". Uso la estática cuando no voy a crear una instancia de una clase porque la clase es una única clase global utilizada en todo el código.

Continuó mencionando algo que involucra burlas, técnicas IOC / DI que no pueden usarse con código estático. Él dice que es desafortunado cuando las bibliotecas de terceros son estáticas debido a su inestabilidad.

¿Es este otro arquitecto correcto?

actualización: aquí hay un ejemplo:

APIManager: esta clase mantiene los diccionarios de API de terceros a los que llamo junto con el próximo tiempo permitido. Hace cumplir los límites de uso de API que muchos terceros tienen en sus términos de servicio. Lo uso donde sea que esté llamando 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 TPL en C #.

    
pregunta Infin8Loop 13.08.2012 - 23:53

10 respuestas

115

Depende de si las clases estáticas mantienen el estado o no. Personalmente, no tengo ningún problema con las funciones sin estado lanzadas juntas en una clase estática.

    
respondido por el Larsenal 13.08.2012 - 23:57
90

Él es demasiado general al respecto. Él es correcto, obstaculiza las pruebas. Sin embargo, las clases y los métodos static tienen su lugar y realmente depende del contexto. Sin ejemplos de código realmente no se puede decir.

  

Uso estática cuando no voy a crear una instancia de una clase porque la clase es una única clase global utilizada en todo el código.

Esto puede ser un olor a código severo. ¿Para qué estás usando las clases? Para mantener los datos? ¿Para acceder a una base de datos? Entonces él tiene razón. Debería consultar 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 funcionan con los parámetros que proporciona, por lo general están bien.

    
respondido por el Femaref 13.08.2012 - 23:56
27
  

Lo verifiqué y 1/4 de mis clases están marcadas como "estáticas". yo suelo   estática cuando no voy a crear una instancia de una clase porque   la clase es una clase global única utilizada en todo el código.

Lo mejor que puedes hacer es probar y probar tu código por unidad. Intente diseñar pruebas que sean repetibles, independientes, simples y pruebe solo un método a la vez. Trate de ejecutar sus pruebas en orden aleatorio diferente. ¿Se puede conseguir una construcción "verde" estable?

Si es así, ese es un punto válido para defender tu código. Sin embargo, si tiene dificultades, tal vez debería buscar métodos basados en la instancia.

    
respondido por el oleksii 14.08.2012 - 00:20
10

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 simular automáticamente 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 las dependencias.

Debido a que C # no tiene metaclases, una clase no puede implementar una interfaz que use características estáticas, por lo que las características estáticas de las clases acaban con cualquier esfuerzo por implementar un modelo de objeto puro IoC / DI. Es decir, no puede crear un simulacro para probarlos, y tiene que crear dependencias reales.

Si su empresa / proyecto tiene una gran inversión en IoC, esta es una preocupación razonable, y el dolor que está atravesando es por la ganancia 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 con métodos estáticos: la estrategia de diseño de singleton, por ejemplo. Yo mismo estoy menos inclinado a las clases estáticas porque creo que tienden a perder las ventajas de la OO, pero hay veces en que 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 deben estar en clases estáticas en C #. Eso es legítimo, y es un ejemplo de cómo la IoC pura no funciona muy bien en C #, al menos si intentas aprovechar la amplitud del lenguaje.

    
respondido por el jwrush 14.08.2012 - 00:06
10

Las respuestas ya publicadas cubren muchos puntos realmente buenos, pero hay uno que parece faltar:

Los campos estáticos son nunca recogida de basura.

Esto es realmente importante si tienes una aplicación con muchas limitaciones 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 han cubierto esto con suficiente detalle.

    
respondido por el riwalk 17.08.2012 - 05:13
5

Las clases estáticas a veces se usan mal y deberían ser:

  • un singleton (donde la clase no estática tiene un miembro estático y una variable de instancia pública estática para recuperarla / crearla solo una vez.
  • un método en otra clase (donde el estado importa). Si tiene un miembro que no usa datos de esa clase, probablemente no debería ser parte de esa clase.

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.

    
respondido por el Michel Keijzers 14.08.2012 - 02:35
4

Los métodos estáticos están bien de 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 hacerlo.

    
respondido por el k rey 02.05.2014 - 19:35
1

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. No soy un experto, pero esto ha estado funcionando para mí hasta ahora.

ejemplo de PHP:

class vendorData {
  private static $data_table = 'vendor_data'; // static property
  private $id; // instance property
  private $name; // instance property

  public function __construct($vendor_id) {
    if(!self::validId($vendor_id) ) { // static method
      return false; // id doesn't exist
    }
    $this->id = $vendor_id; // id has been validated
    $this->getProperties(); // object method
  }

  private static function validId($vendor_id) {
    // send db query to find if the id exists
    // return true/false;
  }

  private function getProperties() { // object method
    $sql = "SELECT * FROM '{self::$data_table}' // using static property
        WHERE 'id' = {$this->id}"; // using object instance property
    // get resultset
    foreach($result as $property => $value) {
      $this->$property = $value; // object instance properties all set
    }
  }

  // and here
  public static function getBy($property,$value) { // static method to return object array
    $sql = "SELECT 'id' FROM '{self::$data_table}' // using static property
      WHERE '$property' = '$value'";
    // send query, get $ids array
    $obj_array = array();
    foreach($ids as $id) {
      // create array of current class objects using special static keyword
      // meaning of static here is different than in property/method declarations
      $obj_array[$id] = new static($id);
    }
    return $obj_array;
  }
}
    
respondido por el Buttle Butkus 14.08.2012 - 05:24
1

Diré que los principios que tienen están bien, pero la afirmación (no usar estadísticas) puede ser incorrecta. ¿Cuánto es la cobertura de su código? Si el número es alto y se siente cómodo con las pruebas de unidad de su aplicación, entonces está bien. Si no, entonces sugiero revisar el código. Puede encontrar que las clases estáticas son la razón o no, dependerá de muchas cosas.

    
respondido por el ivowiblo 14.08.2012 - 06:13
-3

Las clases con métodos estáticos abusan de los principios de la POO. Ya no es un OOP, es una programación orientada a clases COP.

Raramente tienen una "personalidad" clara (uso mi metáfora humana aquí), o identidad. Así que no saben quiénes son. Este solo punto es suficiente para deshacerse de este concepto en OOP, pero hay más de ellos.

El siguiente es una consecuencia del primer punto. Como estas clases no saben quiénes son, tienden a ser grandes o enormes.

El tercero hace que tu código sea absolutamente imposible de mantener. 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 simplemente mirando la firma del constructor.

Lentamente, pero inevitablemente, su código se está volviendo cada vez menos cohesivo, ya que las dependencias ocultas están mal controladas. Parecen invisibles. ¡Y es tan fácil agregar otro! No tienes que modificar la firma de ningún método. Todo lo que tienes que hacer es llamar a un método estático. Y lo que sigue un código feo ...

Ok, probablemente ya lo has adivinado. El acoplamiento apretado es a menudo un asistente de baja cohesión. Si hay muchos clientes que utilizan alguna clase, entonces el acoplamiento se está haciendo más apretado. Y hay una gran seducción en el uso de una clase o método ya escrito que solo requiere una pequeña corrección. Un solo parámetro-parámetro de método.

¿Qué usar en lugar de los métodos estáticos? Bueno, mi sugerencia es OOP. ¿Por qué no intentarlo?

    
respondido por el Zapadlo 19.10.2017 - 14:16

Lea otras preguntas en las etiquetas