Digamos que quiero construir algunas funciones de utilidad para hacer algunas matemáticas básicas con la BigDecimal
s, por ejemplo, quiero tener una función que calcule el promedio de a List<BigDecimal>
.
¿Cuál es el mejor enfoque? ¿Una función estática o una clase de utilidad?
public static BigDecimal computeAverage(List<BigDecimal> numbers)
o
public class BigDecimalUtil
public computeAverage(List<BigDecimal> numbers)
Respuestas:
Probablemente voy a regalar mis inclinaciones de C # de la peor manera posible, pero siempre recomendaría métodos estáticos dentro de las clases de utilidad. Esto te da lo mejor de ambos mundos. Los beneficios organizativos de la clase con la usabilidad de los métodos a los que se accede sin necesidad de instanciar un objeto para usarlos. Si su clase de utilidad tiene una razón para variar ocasionalmente su comportamiento, entonces ya está bien posicionado para hacerlo mediante la introducción de herencia / interfaces más tarde si es necesario. Si desea que su diseño sea un poco más portátil, encontrará que el paradigma se transferirá más fácilmente a otros lenguajes OO.
fuente
Si desea realizar funciones de utilidad, conectadas por algún tema, cree una clase para ellas, conviértalas en estáticas en esa clase y haga que un constructor de esa clase sea privado, para eliminar la posibilidad de dar una instancia accidental. Entonces, usa la segunda variante, pero oculta el constructor.
Hay una posibilidad más: no hacer ningún constructor y hacer que esta clase sea abstracta. Pero de esta manera no puede usar la instancia de la clase no solo fuera, sino también dentro de ella. Entonces, creo que esta segunda variante es demasiado estricta para ti. Elígete a ti mismo.
fuente
Estoy de acuerdo con @Gangnus en que una clase de "envoltura" estática tiene sentido si los métodos de clase individuales siempre se utilizarán de forma aislada, y esto a menudo será una buena respuesta.
Sin embargo, puede haber algún valor en una clase no estática, con métodos no estáticos, si tiene cálculos relacionados que puedan usarse juntos. Por ejemplo, la construcción de un
ListStatsUtil
objeto conList<BigDecimal>
pasado al constructor, que podría ser conveniente para el accesogetStandardDeviation
,getVariance
ygetAverage
en secuencia sin pasar de nuevo en el objeto. Esto puede ser más elegante, pero también podría funcionar mejor, especialmente si están involucradas operaciones computacionalmente costosas que pueden optimizarse en todas las operaciones al compartir el estado privado dentro del objeto.fuente
super()
sentido el constructor privado para una clase estática en Java?He votado a favor de codificar la respuesta en voz alta y me gustaría ampliarla un poco.
Ajustar colecciones en clases es algo que siempre he intentado hacer: mi regla es "Nunca pasar una colección desnuda". Los mayores fracasos de OO que he visto es cuando las personas tienen miedo de agregar métodos a los que pertenecen. En su caso, los métodos pertenecen a la colección (Totalmente obvio si lo piensa), así que póngalos allí envolviendo la colección y para poner la guinda del pastel, solo exponga la funcionalidad que necesita fuera de su nueva clase (como codingoutloud hizo) para que pueda ver a su clase pequeña y única y comprender fácilmente todo lo que manipula esa colección.
No tiene que resolver todos los problemas posibles porque es todo su código, puede editar el contenedor de colección tan fácilmente como puede editar las otras clases que interactúan con él. Esto le permite incluir otro código en la clase según sea necesario; si nunca expone la colección, se hará rápidamente evidente qué código pertenece en el contenedor.
Esto también le da un control completo sobre la colección para que pueda evitar que entre en un estado inconsistente con su función (por ejemplo, si ninguna entrada en la colección puede ser nula, ¡simplemente evite que alguien ingrese un nulo!)
La mayor parte del código OO incorrecto que he visto se ha creado porque alguien eligió escribir utilidades estáticas o código en línea que pertenecían a objetos a los que no podían agregar código en lugar de envolver los objetos ofensivos en un código propio que podrían modificar .
fuente
Si no me equivoco y Java sigue siendo un lenguaje OO puro, no puede tener funciones sin envolverlas en una clase.
Entonces su respuesta es: ambas, una función estática envuelta en una clase de utilidad estática, no muy diferente de la clase Math.
fuente
¿Qué tal una interfaz CalcAverageStrategy que se inyecta, y luego puede tener implementaciones de modo medio / medio / modo inyectadas cuando sea necesario?
Cada implementación es fácil de probar, y también fácil de burlar para probar.
fuente