1

I have to do a refactoring of a method and run into a problem where this method gets called with different expectation for return values. This is basically what i have at this point (abstracted from real method and classnames).

public static List<TypeA> calculationMethod(...)
{
    List<TypeA> aTypes = new ArrayList<TypeA>;

    //this one is used to calculate some stuff inside this method
    List<TypeB> bTypes = new ArrayList<TypeB>;


    // generation of objects of TypeA and TypeB and more

    // use bTypes to check if aTypes is fine

    return aTypes;
}


public void method1()
{
    List<TypeA> aTypes = calculationMethod(...)
    //do other stuff with aTypes
}

public void method2()
{
    List<TypeA> aTypes;
    List<TypeB> bTypes;

    // here is the problem, i need to get both lists from calculationMethod
    aTypes = calculationMethod(...);
}

The calculationMethod returns a list with TypeA objects which is fine for method1 (90% of my calls) but not for method2, because there i need the second list with objects of TypeB to do further verification.

I came up with the following solutions with which i have some problems.

Call by reference Instead of returning a value i could just put the list in the method parameters and expect it to be filled after calculationMethod is done. This is actually where i came from and where i don't want to go again. Something like:

public static void calculationMethod(List<TypeA> aTypes, List<TypeB> bTypes, ...)
{
    aTypes.add(...);
    bTypes.add(...);
}

Switch return type of calculationMethod Instead of returning a list, i could return a tuple with both lists in it. But since i only need one of the lists in most cases this seems like i weaken my method contract and readability of my code.

public static Tuple<List<TypeA>, List<TypeB>> calculationMethod(...)
{
    // do stuff

    return new Tuple<>(aTypes,bTypes);
}

Split method I could also split the method (and rename them) so i have two methods and i can call the one i need at the moment. But this would create duplicate code, at least to some extend, because the code used in calculationMethod can not be put into another method so easily.

public static List<TypeA> calculationMethod1(...)
{
    //code
    return aTypes;
}

public static Tuple<List<TypeA>, List<TypeB>> calculationMethod2(...)
{
    // same code
    return new Tuple<>(aTypes,bTypes);
}

TL;DR Is there a refactoring pattern so i can refactor a method that uses call by reference for its parameters to handle multiple return types?

edit The second list contains Boolean and is used to verify the initialization of the objects of list one (TypeA). Usually it is enough if i know that bTypes only contains true. But there is one case where i want that bTypes contains false. And this is the case for method2 where i want bTypes to do further checks outside of calculationMethod.

public static List<TypeA> calculationMethod(...)
{
    List<TypeA> aTypes = new ArrayList<TypeA>;
    List<Boolean> bTypes = new ArrayList<TypeB>;

    TypeA typeA = new TypeA(...);
    bTypes.add(validateInit(typeA));

    Boolean initOK = true;
    for(Boolean b: bTypes)
    {
        if(!b)
            initOK = false;
    }
    if(initOK)
    {
        return aTypes;
    }else 
        return null;
} 
Stefan Lindner
  • 321
  • 1
  • 10
  • 20
  • Possible duplicate of [How to return multiple objects from a Java method?](http://stackoverflow.com/questions/457629/how-to-return-multiple-objects-from-a-java-method) – shmosel Jan 13 '17 at 08:11
  • See also [How to return 2 values from a Java method?](http://stackoverflow.com/questions/2832472/how-to-return-2-values-from-a-java-method) – shmosel Jan 13 '17 at 08:12
  • He doesn't want to return multiple values. He wants to return one of multiple types, depending on some unknown condition. – Kayaman Jan 13 '17 at 08:14
  • 1
    There are ways to achieve this, but it would be helpful to know more about why you would choose one type over the other, are the types related to each other somehow, is there perhaps a possibility to do an *extract method* refactoring to the calculation method to avoid duplicating the code, etc. – Kayaman Jan 13 '17 at 08:16
  • I have read them both before i asked this question. I don't want to know how to return multiple objects from a method. A wrapper is actually my second solution. – Stefan Lindner Jan 13 '17 at 08:17
  • It's still very hard to come up with a good solution, when the problem is abstracted that much. You either return a `List` or a `List` that tells about the state of the `MyObjects`? I'm having a hard time imagining how they would share a lot of code in `calculationMethod()`. Can you explain better, or are you trying to "obfuscate" because of an NDA or similar? – Kayaman Jan 13 '17 at 08:34
  • @Kayaman i have updated my question again. The calculationMethod initializes objects of TypeA and checks the initialization. In most cases its just fine when the init of all objects is ok. But i have a case where i want that the initialization of one object of TypeA has failed. That is where i need bTypes outside of calculationMethod. – Stefan Lindner Jan 13 '17 at 08:49

1 Answers1

4

This is a design issue, when you have to return 2 objects from a method, that means the method does more than it should do. You may have 2 options depending on the implementation you already have in your hands;

Split the method to do one meaningful thing only OR encapsulate the Lists in an object, populate it in the method and return that.

public class Types {
    List<TypeA> typeAs;
    List<TypeB> typeBs;
}
Y.E.
  • 902
  • 7
  • 14
  • The wrapper is not what i want, but i see that this would be a fix for my problem. I rather think you are right with the design issue. I'll check that. – Stefan Lindner Jan 13 '17 at 08:50
  • I accept this answer for the design issue statement. I can perform an extract method refactoring on some lines of code inside the _calculationMethod_. – Stefan Lindner Jan 13 '17 at 09:30