Estoy escribiendo un método en Java:SECO: Minimizar el código repetido en Java
List<Foo> computeFooList(/* arguments */)
{
/* snip */
}
me gustaría escribir un segundo método con exactamente la misma lógica, pero un diferente tipo de retorno:
List<String> computeStringList(/* same arguments */)
{
/* snip */
}
Estoy tratando de encontrar una forma no hackish de minimizar la cantidad de código repetido entre los dos métodos. El solamente diferencia lógica entre los dos es que, cuando la adición de un objeto a la lista que se devuelve, el primer método agrega el acutal Foo
:
List<Foo> computeFooList(/* arguments */)
{
List<Foo> toReturn = ...
...
for (Foo foo : /* some other list of Foo */)
{
if (/* some condition */)
{
toReturn.add(foo);
}
}
...
return toReturn;
}
y la segunda añade una representación String
de la Foo
:
List<String> computeStringList(/* same arguments */)
{
List<String> toReturn = ...
...
for (Foo foo : /* some other list of Foo */)
{
if (/* some condition */)
{
toReturn.add(foo.toString());
}
}
...
}
En realidad, no es exactamente que simple. No quiero agregar un Foo
a toReturn
a menos que esté absolutamente seguro de que pertenece allí. Como resultado, esa decisión se toma por- foo
usando funciones auxiliares. Con dos versiones diferentes de los métodos, necesitaría también diferentes versiones de las funciones de ayuda; al final, estaría escribiendo dos conjuntos de métodos casi idénticos, pero para un pequeño tipo genérico.
¿Puedo escribir un método único que contiene toda la lógica de toma de decisiones, pero puede generar ya sea un List<Foo>
o una List<String>
? ¿Es posible hacer esto sin usar tipos sin procesar List
(mala práctica en genéricos terrestres) o comodines List<?>
? Imagino una implementación que se ve algo como esto:
List<Foo> computeFooList(/* args */)
{
return computeEitherList(/* args */, Foo.class);
}
List<String> computeStringList(/* args */)
{
return computeEitherList(/* args */, String.class);
}
private List<???> computeEitherList(/* args */, Class<?> whichType)
{
/* snip */
}
¿Hay alguna manera agradable, elegante de hacer esto? He estado jugando con métodos genéricos, pero no veo la manera de hacerlo. Incluso andar sucio con la reflexión no me ha llevado a ninguna parte (tal vez necesito algo como TypeToken
? ... eww).
que podría estar interesado en este nuevo sitio StackExchange: http://codereview.stackexchange.com/ – Mchl
@Mchl: ** * Gah * - ahora está en –