DRY: Минимизация повторяющегося кода в Java

Я пишу метод на Java:

List computeFooList(/* arguments */)
{
    /* snip */
}

Я бы хотел написать второй метод с точно такой же логикой, но с другим типом возвращаемого значения:

List computeStringList(/* same arguments */)
{
    /* snip */
}

Я пытаюсь найти нехакерский способ минимизировать количество повторяющегося кода между двумя методами. Единственное логическое различие между ними состоит в том, что при добавлении объекта в возвращаемый список первый метод добавляет acutal Foo :

List computeFooList(/* arguments */)
{
    List toReturn = ...
    ...
    for (Foo foo : /* some other list of Foo */)
    {
        if (/* some condition */)
        {
            toReturn.add(foo);
        }
    }
    ...
    return toReturn;
}

, а второй добавляет ] Строковое представление Foo :

List computeStringList(/* same arguments */)
{
    List toReturn = ...
    ...
    for (Foo foo : /* some other list of Foo */)
    {
        if (/* some condition */)
        {
            toReturn.add(foo.toString());
        }
    }
    ...
}

На самом деле это не совсем , что просто. Я не хочу добавлять Foo в toReturn , если я не совсем уверен, что он принадлежит именно этому месту. В результате это решение принимается per- foo с использованием вспомогательных функций. С двумя разными версиями методов мне также потребовались бы разные версии вспомогательных функций - в конце концов, я бы написал два набора почти идентичных методов, но для одного маленького общего типа.


Могу ли я я написать единственный метод, который содержит всю логику принятия решений, но может генерировать либо List , либо List ? Можно ли сделать это без использования необработанных типов List (плохая практика в мире дженериков!) Или типов с подстановочными знаками List > ? Я представляю себе реализацию, которая выглядит примерно так:

List computeFooList(/* args */)
{
    return computeEitherList(/* args */, Foo.class);
}

List computeStringList(/* args */)
{
    return computeEitherList(/* args */, String.class);
}

private List computeEitherList(/* args */, Class whichType)
{
    /* snip */
}

Есть ли какой-нибудь красивый, элегантный способ сделать это? Я играл с универсальными методами, но могу ' не вижу способа сделать это. Даже возня с отражением меня ни к чему не привела (может, мне нужно что-то вроде TypeToken ? ... фу).

7
задан Matt Ball 26 January 2011 в 21:41
поделиться