oop - que - ¿Es una mala práctica para una clase tener solo campos y métodos estáticos?
que es un atributo estatico (14)
Tengo una clase que consiste solo en variables miembro estáticas y métodos estáticos. Básicamente, sirve como una clase de utilidad de propósito general.
¿Es una mala práctica para una clase contener solo variables de miembros estáticos y métodos estáticos?
De acuerdo con una interpretación rígida de Object Oriented Design, una clase de utilidad es algo que debe evitarse.
El problema es que si sigues una interpretación rígida, necesitarás forzar a tu clase a formar un objeto para poder lograr muchas cosas.
Incluso los diseñadores de Java hacen clases de utilidad (java.lang.Math viene a la mente)
Tus opciones son:
double distance = Math.sqrt(x*x + y*y); //using static utility class
vs:
RootCalculator mySquareRooter = new SquareRootCalculator();
mySquareRooter.setValueToRoot(x*x + y*y);
double distance;
try{
distance = mySquareRooter.getRoot();
}
catch InvalidParameterException ......yadda yadda yadda.
Incluso si evitáramos el método detallado, podríamos terminar con:
Mathemetician myMathD00d = new Mathemetician()
double distance = myMathD00d.sqrt(...);
en este caso, .sqrt () sigue siendo estático, entonces, ¿qué sentido tendría crear el objeto en primer lugar?
La respuesta es crear clases de utilidad cuando su otra opción sería crear algún tipo de clase "Trabajador" artificial que no tenga o tenga poco uso para las variables de instancia.
Es perfectamente razonable. De hecho, en C # puede definir una clase con la palabra clave estática específicamente para este propósito.
Esta es la forma típica en que se diseñan las clases de utilidad y no hay nada de malo en ello. Ejemplos famosos incluyen o.a.c.l.StringUtils , o.a.c.d.DbUtils , o.s.w.b.ServletRequestUtils , etc.
Este enlace http://java.dzone.com/articles/why-static-bad-and-how-avoid parece ir en contra de la mayoría de las respuestas aquí. Incluso si no contiene variables miembro (es decir, sin estado), una clase estática aún puede ser una mala idea porque no se puede burlar o extender (subclasificar), por lo que está derrotando algunos de los principios de OO.
La clase Collections en Java SDK solo tiene miembros estáticos.
Entonces, ahí lo tienes, siempre que tengas una justificación adecuada, no es un mal diseño
Los métodos de utilidad a menudo se colocan en clases con solo métodos estáticos (como StringUtils
). Las constantes globales también se colocan en su propia clase para que puedan ser importadas por el resto del código (atributos public final static
).
Ambos usos son bastante comunes y tienen constructores privados predeterminados para evitar que se creen instancias. Declarar la clase final evita el error de intentar anular los métodos estáticos.
Si por static member variables
no quiere decir constantes globales, puede colocar los métodos que acceden a esas variables en una clase propia. En ese caso, ¿podría elegir qué hacen esas variables en su código?
Los métodos estáticos no me preocupan demasiado (a excepción de las pruebas).
En general, los miembros estáticos son una preocupación. Por ejemplo, ¿qué ocurre si tu aplicación está agrupada? ¿Qué pasa con el tiempo de puesta en marcha? ¿Qué tipo de inicialización está teniendo lugar? Para una consideración de estos temas y más, vea este artículo de Gilad Bracha.
No me preocuparía una clase de utilidad que contenga métodos estáticos.
Sin embargo, los miembros estáticos son esencialmente datos globales y deben evitarse. Pueden ser aceptables si se utilizan para el almacenamiento en caché de los resultados de los métodos estáticos y demás, pero si se utilizan como datos "reales" que pueden conducir a todo tipo de problemas, como las dependencias ocultas y las dificultades para configurar las pruebas.
No, no lo creo en absoluto. Es una práctica peor tener una clase llena de métodos de instancia que en realidad no dependen de una instancia particular. Hacerlos estáticos le dice al usuario exactamente cómo están destinados a ser utilizados. Además, evita instancias innecesarias de esta manera.
EDITAR: como una idea de último momento, en general creo que es bueno evitar el uso de características del lenguaje "solo porque", o porque piensas que esa es la "forma de Java para hacerlo". Recuerdo mi primer trabajo en el que tuve una clase llena de métodos de utilidad estáticos y uno de los programadores senior me dijo que no estaba aprovechando al máximo el poder de OO de Java haciendo todos mis métodos "globales". Ella no estaba en el equipo 6 meses después.
Si bien estoy de acuerdo con el sentimiento de que suena como una solución razonable (como otros ya han indicado), una cosa que tal vez desee considerar es, desde el punto de vista del diseño, por qué tiene una clase solo para fines de "utilidad". Son esos funcionales realmente generales en todo el sistema, o están realmente relacionados con una clase específica de objetos dentro de su arquitectura.
Mientras lo haya pensado, no veo ningún problema con su solución.
Siempre que la clase no tenga un estado interno y sea esencialmente lo que se conoce como clase de hoja (las clases de utilidad pertenecen a esta categoría), en otras palabras, es independiente de otras clases. Está bien.
La clase de Math
es un buen ejemplo.
Simplemente no te dejes llevar por eso. Observe que la clase java.lang.Math solo se trata de funciones matemáticas. También podría tener una clase StringUtilities que contenga funciones comunes de manejo de cadenas que no están en la API estándar, por ejemplo. Pero si su clase se llama Utilidades, por ejemplo, eso es una pista de que es posible que desee dividirla.
Suena razonable.
Nota: Las clases que hacen esto a menudo tienen un constructor no-arg privado solo para que el compilador genere un error si un programador intenta crear una instancia de la clase estática.
Tenga en cuenta también que Java introdujo específicamente la importación estática: ( http://en.wikipedia.org/wiki/Static_import )
La importación estática es una característica introducida en el lenguaje de programación Java que los miembros (campos y métodos) definieron en una clase como estática pública para ser utilizada en código Java sin especificar la clase en la que se define el campo. Esta característica se introdujo en el lenguaje en la versión 5.0.
La función proporciona un mecanismo seguro para incluir constantes en el código sin tener que hacer referencia a la clase que originalmente definió el campo. También ayuda a desaprobar la práctica de crear una interfaz constante: una interfaz que solo define constantes y luego escribe una clase que implementa esa interfaz, que se considera un uso inapropiado de las interfaces [1].
El mecanismo se puede usar para hacer referencia a miembros individuales de una clase:
import static java.lang.Math.PI;
import static java.lang.Math.pow;
o todos los miembros estáticos de una clase:
import static java.lang.Math.*;