2009-12-21 21 views
68

Tengo una clase que consta de solo de variables de miembros estáticos 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 tener solo campos y métodos estáticos?

¿Es una mala práctica para una clase contener solo variables de miembros estáticos y métodos estáticos?

+28

'java.lang .Math' es 100% de métodos estáticos con un constructor 'privado' (no se puede crear una instancia). – Asaph

+0

No estoy seguro de si esta pregunta ha sido formulada en este foro. ¿Pero es una mala práctica para una clase tener solo campos estáticos? He visto muchas de esas clases y, en mi opinión, no encajan en OOP. – ka3ak

+0

@ ka3ak Las clases que solo tienen campos estáticos se tratan parcialmente en algunas respuestas a esta pregunta. –

Respuesta

85

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 de idioma "solo porque", o porque cree 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.

+97

recuérdame que no me interponga en tu camino. – akf

+7

Ha: no es exactamente lo que quise dar a entender – danben

3

Es perfectamente razonable. De hecho, en C# puede definir una clase con la palabra clave estática específicamente para este propósito.

13

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.

+4

Un constructor predeterminado privado también evita la subclasificación de su clase estática. – David

+1

¿Hay alguna razón por la que desee subclasificar una clase estática? (No puedo pensar en uno ... No soy un gurú del idioma) –

+4

La prevención de la subclasificación en este caso es un "pro". Es posible que alguien más que trabaje en su proyecto accidentalmente intente y subclasifique su clase estática (a través de un error tipográfico o malentendido). Al agregar un constructor predeterminado privado, está agregando más significado a su clase al imponer de forma más estricta cómo se puede usar. – David

2

Tenga en cuenta también que Java introdujo específicamente la importación estática: (http://en.wikipedia.org/wiki/Static_import)

importación estática es una característica introducida en el lenguaje de programación Java que los miembros (campos y métodos) definen en una clase como públicos static para ser utilizado 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 característica proporciona un mecanismo typesafe para incluir constantes en código sin tener que hacer referencia a la clase que originalmente define el campo . También ayuda a despreciar la práctica de crear una interfaz constante : una interfaz que sólo define constantes a continuación, escribiendo una clase incorporación de dicha interfaz, que es considera un uso inadecuado de las interfaces [1].

El mecanismo puede ser utilizado 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.*; 
+0

Creo que esto es un poco fuera de tema por lo que está preguntando. La importación estática no tiene nada que ver con si una clase SOLO tiene miembros estáticos; funciona si hay alguno. – danben

+1

Buena información y un gran argumento sobre por qué esto es algo que debemos hacer. – Chuck

+0

Lo siento, no estoy de acuerdo, creo que es un argumento para tener métodos estáticos, pero no dice nada de tener clases que no están destinadas a ser instanciadas. – danben

3

Sólo don' 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.

1

La clase Collections en Java SDK solo tiene miembros estáticos.

Por lo tanto, hay que ir, siempre y cuando usted tiene una justificación adecuada - no es un mal diseño

1

métodos de utilidad se colocan a menudo en las clases con sólo métodos estáticos (. Como StringUtils) constantes globales también se colocan en su propia clase para que puedan ser importados por el resto del código (public final static atributos.)

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 quiso decir las constantes globales, es posible que desee colocar los métodos que acceden a esas variables en una clase propia. En ese caso, ¿podrías elegir qué hacen esas variables en tu código?

1

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, entonces deberás forzar a tu clase a algún tipo de objeto para lograr muchas cosas.

Incluso los diseñadores de Java crea clases de utilidad (java.lang.Math viene a la mente)

Las 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 tuviéramos que evitar el método detallado, todavía podríamos terminar con:

Mathemetician myMathD00d = new Mathemetician() 
double distance = myMathD00d.sqrt(...); 

en este caso, .sqrt() sigue siendo estático, entonces, ¿qué sentido tiene 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.

2

Aunque estoy de acuerdo con el sentimiento de que suena como una solución razonable (como otros ya han mencionado), una cosa que quizás desee considerar es, desde el punto de vista del diseño, ¿por qué tiene una clase solo para "utilidad" propósitos. 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.

17

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 Math es un buen ejemplo.

+0

¿Tiene un buen enlace/artículo con respecto a las clases de hoja/utilidad? –

9

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 estas cuestiones y más, visita this article por Gilad Bracha.

+2

+1 para distinguir entre funciones estáticas (finas) y estáticas (dudosas) – mikera

0

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.

1

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 puede ser burlada o extendida (subclasificada), por lo que está anulando algunos de los principios de OO

Cuestiones relacionadas