15

I need to return 2 values from a method. My approach is as follows:

  1. create an inner class with 2 fields that will be used to keep those 2 values
  2. put the method inside that class
  3. instantiate the class and call the method.

The only thing that will be changed in the method is that in the end it will assign those 2 values to the fields of the instance. Then I can address those values by referencing to the fields of that object.

Is it a good design and why?

3
  • Another option (probably a bad one): see BitInteger[] java.math.BigInteger.divideAndRemainder(BitInteger val). It returns 2 integers as its return values in an array. Commented Oct 1, 2012 at 14:30
  • 1
    What type are the two values you want to return ? Commented Oct 1, 2012 at 15:18
  • Possible duplicate - stackoverflow.com/questions/12668186/… .
    – Random42
    Commented Oct 1, 2012 at 15:31

5 Answers 5

15

I would argue this along the following lines:

  • Why exactly does your method return multiple values? What kind of cohesion are we talking about - should those values actually be fields on a single class, or are they just coincidentally returned by the same method, but otherwise unrelated? If it's the latter, you might want to consider splitting the method into two methods, rather. Edit: use your judgement here; sometimes a type of "coincidental" cohesion may be the best option. Another option is to use a pair or tuple construct, although in OOP, these are usually not seen in public APIs (some notable exceptions being standard collections, etc).
  • If the values do deserve to form a class, I would probably advise against using an inner class. Inner classes are typically used as internal implementation details, which are hidden from the outside. Is there any reason why this result shouldn't be a "full-blown" class, in its own right?
  • Other than holding data, what operations are applicable to this new class? In object oriented design, you want to have the related behaviour close to the relevant data (which seem to be your intentions, too). Should the method you are referring to not live on this class rather?

To summarise, I would see if I can turn this "data object" into a fledged-out class with both data and behaviour. As an additional comment, you may want to make the class immutable, since its state is set once. Making it immutable will help prevent it being incorrectly set, or modified later (say, someone setting one of the fields to null and passing it along).

Edit: As Patkos Csaba correctly points out, the principle being applied here is the Single Responsibility Principle (SRP) - the class you are trying to create should really have one responsibility (defined as a reason for changing). This design guideline should help you figure out whether your two fields belong in a single class, or not. To stick with the Wikipedia example, your class could be a seen as a type of report, in which case it's conforming to SRP, but it's difficult to comment without further information.

16
  • While I agree with the general idea of this answer, there are legitimate cases when two closely related pieces of data are calculated together, but there's no sense to tie them together otherwise anywhere else in the program. In such a case it may be clean enough to return something like Pair<OneClass, AnotherClass>. Some people would disagree. In any case, Pair should be an implementation detail and never appear in a public API method.
    – 9000
    Commented Oct 1, 2012 at 15:51
  • @9000 I agree; I actually meant the word consider to be taken literally in this case, i.e. splitting the method may not always be the best solution, it's just a rough indication in that direction. I'll make an edit along those lines.
    – Daniel B
    Commented Oct 1, 2012 at 16:01
  • 1
    Good answer. The only thing I would add is a reference to the Single Responsibility Principle (SRP) (en.wikipedia.org/wiki/Single_responsibility_principle). If checked, it is very possible that the method in discussion is just a simple violation of SRP and a split is a simple solution. In my experience, whenever a method wants to return 2 or more values, in 90% of the cases there are 2 methods there or another class should be extracted. Commented Oct 2, 2012 at 9:23
  • @PatkosCsaba thanks, made an edit to include it. I normally stick to explaining things in terms of coupling and cohesion, but I guess the SOLID principles are seen as the basic rules to live by these days.
    – Daniel B
    Commented Oct 2, 2012 at 9:51
  • @DanielB: I see SOLID as higher level and probably easier to understand concepts. Coupling and cohesion are still the baseline, but they are more lower level. SOLID makes great use of coupling and cohesion to explain it's principles and to present them on a more generic level. Commented Oct 2, 2012 at 10:14
10

There's the concept of a Tuple which is featured in other languages, such as Python.

One could return an instance of this genericized class which is easily re-usable:

public class TypedTuple<L, R> implements Serializable {
private static final long serialVersionUID = 1L;

  protected L left;
  protected R right;

  protected TypedTuple() {
    // Default constructor for serialization
  }

  public TypedTuple(L inLeft, R inRight) {
    left = inLeft;
    right = inRight;
  }

  public L getLeft() {
    return left;
  }

  public R getRight() {
    return right;
  }
}
1
  • 2
    It's sometimes nice to have a generic static method create(), to avoid having to specify the type parameters in the constructor. Also, I would name this class Pair rather than Tuple, given it can only represent 2-tuples of values.
    – augurar
    Commented Jul 11, 2014 at 20:40
5

It seems that this class is taking responsibility away from another class, and this makes me think that this design isn't great.

For a method that returns multible values, I would rather

  • return a generic containter (e.g. a List or Map) containing the return values

or

  • create a Class for the return value, which contains just of the necessary fields + getters + a constructor with all fields

Example for the second option:

public Class FooBarRetval {
   private String foo;
   private int bar;

   public FooBarRetval (String foo, int bar) {
      this.foo = foo;
      this.bar = bar;
   }

   public String getFoo() {
      return foo;
   }

   public int getBar() {
      return bar;
   }
}
4
  • Making the fields public adds the option of altering the values separately, though clearly the values have a relation (otherwise they would not have to be returned by the same method). I would highly discourage this pattern in this special situation. But the main point is, the discussion of public vs. private attributes has nothing to do with OPs question and I see no reason for the last sentence in an otherwise good answer.
    – scarfridge
    Commented Oct 1, 2012 at 14:19
  • The first one should be preferred.
    – Juanin
    Commented Oct 1, 2012 at 15:06
  • scarfridge: Point taken, last sentence removed.
    – user281377
    Commented Oct 2, 2012 at 7:01
  • 2
    Just use public final fields, no reason to waste time with accessors.
    – augurar
    Commented Jul 11, 2014 at 20:41
1

Putting multiple return values from a method into its own class/structure is often used in message based systems that have one class for Request and response. An example of this is Simple Object Access Protocol (SOAP).

Is it a good design and why?

At least it is quite common. If this is good or bad depends on your special usecase.

0

Short answer: You can return an array or a List with the two values.

I personally would write two distinct methods, like

int x = obj.getX();
int y = obj.getY();

Not the answer you're looking for? Browse other questions tagged or ask your own question.