Tengo una clase llena de funciones de utilidad. Crear instancias de una instancia no tiene sentido semántico, pero todavía quiero llamar a sus métodos. ¿Cuál es la mejor manera de lidiar con esto? Clase estática? ¿Resumen?
@matt b: Como David Robles señala en su respuesta, no es necesario que la clase sea final ... no se puede subclasificar porque una subclase no podrá invocar a un constructor de superclases porque es privada. Sin embargo ... no hay daño en ser explícito. Pero jfyi :-).
Artículo 4: imponer la no instantabilidad con un constructor privado
- Intentar imponer la no instantabilidad haciendo un resumen de clase no funciona.
- Se genera un constructor predeterminado solo si una clase no contiene constructores explícitos, por lo que una clase puede hacerse no instantable al incluir un constructor privado:
// Noninstantiable utility classpublicclassUtilityClass{// Suppress default constructor for noninstantiabilityprivateUtilityClass(){thrownewAssertionError();}}
Debido a que el constructor explícito es privado, es inaccesible fuera de la clase. AssertionError no es estrictamente necesario, pero proporciona un seguro en caso de que el constructor se invoque accidentalmente desde dentro de la clase. Garantiza que la clase nunca se instanciará bajo ninguna circunstancia. Este modismo es ligeramente contradictorio, ya que el constructor se proporciona expresamente para que no se pueda invocar. Por lo tanto, es aconsejable incluir un comentario, como se muestra arriba.
Como efecto secundario, este idioma también evita que la clase se subclasifique. Todos los constructores deben invocar un constructor de superclase, explícita o implícitamente, y una subclase no tendría un constructor de superclase accesible para invocar.
Solo para nadar río arriba, los miembros estáticos y las clases no participan en OO y, por lo tanto, son malvados. No, no es malo, pero en serio, recomendaría una clase regular con un patrón singleton para acceder. De esta manera, si necesita anular el comportamiento en cualquier caso en el futuro, no es una reestructuración importante. OO es tu amigo :-)
singleton no es más malvado que la inyección de dependencia :)
irreputable
12
OO tiene su lugar, pero hay momentos en que simplemente no es práctico, o sería un desperdicio de recursos, por ejemplo, algo tan simple como Math.abs (). No hay ninguna razón para crear una instancia de un objeto solo por instanciar un objeto, cuando una llamada de método estático le hubiera servido igual de bien sin ninguna de las sobrecargas de OO. ;)
robar el
2
@rob re OO, estoy de acuerdo, Math.Abs probablemente nunca necesite una instancia. Cuando escucho "tengo una clase de utilidad", veo Math.Avg (), donde ahora necesita agregar soporte para un promedio ponderado. Veo un generador de URL, param in, url out que necesita ser refactorizado para admitir href, o solo url, etc. Por estas razones, tener la clase de utilidad basada en OO puede pagar. Además, ahora dejaré caer la táctica defensiva OO estándar, ¡pruebas! / me ducks
Bennett Dill el
3
comentar los argumentos del "constructor privado": vamos, los desarrolladores no son tan estúpidos; pero son flojos. crear un objeto y luego llamar a métodos estáticos? No va a pasar.
no gastes demasiado tiempo para asegurarte de que tu clase no pueda ser mal utilizada. Ten un poco de fe para tus colegas. y siempre hay una manera de usar mal tu clase sin importar cómo la protejas. Lo único que no puede ser mal utilizado es algo completamente inútil.
Alguien que ha visto (en el código de producción, no solo el código del estudiante) object.staticMethod ¡Creo que sobreestimas las habilidades de Joe Random Programmer! :-P
TofuBeer
2
Clase final y constructor privado (bueno pero no esencial)
No tiene sentido declarar la clase como static. Simplemente declare sus métodos staticy llámelos desde el nombre de la clase como normal, como la clase de Matemáticas de Java .
Además, aunque no es estrictamente necesario hacer que el constructor sea privado, es una buena idea hacerlo. Marcar el constructor como privado evita que otras personas creen instancias de su clase y luego llamar a métodos estáticos desde esas instancias. (Estas llamadas funcionan exactamente igual en Java, solo son engañosas y perjudican la legibilidad de su código).
Respuestas:
Constructor privado y métodos estáticos en una clase marcada como final.
fuente
Según el gran libro "Java efectivo" :
Artículo 4: imponer la no instantabilidad con un constructor privado
- Intentar imponer la no instantabilidad haciendo un resumen de clase no funciona.
- Se genera un constructor predeterminado solo si una clase no contiene constructores explícitos, por lo que una clase puede hacerse no instantable al incluir un constructor privado:
Debido a que el constructor explícito es privado, es inaccesible fuera de la clase. AssertionError no es estrictamente necesario, pero proporciona un seguro en caso de que el constructor se invoque accidentalmente desde dentro de la clase. Garantiza que la clase nunca se instanciará bajo ninguna circunstancia. Este modismo es ligeramente contradictorio, ya que el constructor se proporciona expresamente para que no se pueda invocar. Por lo tanto, es aconsejable incluir un comentario, como se muestra arriba.
Como efecto secundario, este idioma también evita que la clase se subclasifique. Todos los constructores deben invocar un constructor de superclase, explícita o implícitamente, y una subclase no tendría un constructor de superclase accesible para invocar.
fuente
AssertionError
sobre otras alternativas comoIllegalStateException
,UnsupportedOperationException
, etc.?Parece que tiene una clase de utilidad similar a java.lang.Math .
El enfoque allí es la clase final con constructor privado y métodos estáticos.
Pero tenga cuidado con lo que esto hace para la comprobabilidad, le recomiendo leer este artículo
Los métodos estáticos son la muerte de la testabilidad
fuente
Solo para nadar río arriba, los miembros estáticos y las clases no participan en OO y, por lo tanto, son malvados. No, no es malo, pero en serio, recomendaría una clase regular con un patrón singleton para acceder. De esta manera, si necesita anular el comportamiento en cualquier caso en el futuro, no es una reestructuración importante. OO es tu amigo :-)
Mi $ .02
fuente
comentar los argumentos del "constructor privado": vamos, los desarrolladores no son tan estúpidos; pero son flojos. crear un objeto y luego llamar a métodos estáticos? No va a pasar.
no gastes demasiado tiempo para asegurarte de que tu clase no pueda ser mal utilizada. Ten un poco de fe para tus colegas. y siempre hay una manera de usar mal tu clase sin importar cómo la protejas. Lo único que no puede ser mal utilizado es algo completamente inútil.
fuente
fuente
No tiene sentido declarar la clase como
static
. Simplemente declare sus métodosstatic
y llámelos desde el nombre de la clase como normal, como la clase de Matemáticas de Java .Además, aunque no es estrictamente necesario hacer que el constructor sea privado, es una buena idea hacerlo. Marcar el constructor como privado evita que otras personas creen instancias de su clase y luego llamar a métodos estáticos desde esas instancias. (Estas llamadas funcionan exactamente igual en Java, solo son engañosas y perjudican la legibilidad de su código).
fuente
Puede usar la anotación @UtilityClass de lombok https://projectlombok.org/features/experimental/UtilityClass
fuente