Question

In my DAO i have a method where i build 2 different objects and I want to return both of those objects, but i'm not sure what the best way is to do it. I've looked at using ? extends myObject, creating another class that holds both of my objects that i want to return, and just using List<Object>.

Long story short on why i need these similar objects is to display 1 on the screen and the other to use with primefaces dataexporter which doesn't handle lists in an object as far as i'm aware.

Class Person

public class Person() {
  firstName = null;
  lastName = null;
  List<Programs> programs = new ArrayList<Programs>();

  // Getters and setters
}

Class DataExporterPerson

public class DataExporterPerson() {
  firstName = null;
  lastName = null;
  String program = null;

  // Getters and setters
}

DAO method:

public List<SOMETHING> getPeople() {
  // query db for people

  // build both objects

  return ?????
}

Now i understand i can very easily create another object like the one below, but that seems like an inefficient way to do things because i'm basically creating an object just to return from 1 method.

public class PersonTransporter() {
  Person person = null;
  DataExporterPerson = null;
}

What is the best way to handle this scenario?

EDIT

The reason that i'm trying to return 2 objects in 1 method is because this is a DAO method that queries the database and builds 2 objects based on the data in the query. I don't want to break it up into 2 methods because i don't want to query the db twice if i don't need to.

Was it helpful?

Solution

You can either handle this through inheritance, or containment.

You can have Person and DataExporterPerson extend something like AbstractPerson. However, since you have not already done so, then it is probably inappropriate to do inheritance.

I think it was Effective C++ that talked about how containment is better than inheritance. IIRC the reason stated is that containment is more loosely coupled than inheritance.

Here you would have a object that contains both Person and DataExporterPerson. Your method would populate one of those for this union type object, and by seeing which one is null you would know which one you actually have.

public class DBPersonUnion {
  private Person person = null;
  private DataExporterPerson dataExporterPerson = null;

  //getters and setters.
}

OTHER TIPS

If your method need to return two different types this is a hint that there is something wrong with your architecture or method logic.

What you can do ?

  • Create a class that will logically join the elements,
  • Introduce common interface that, both class will implement,
  • Implement two methods fist return with object, that second use a parameter and return the second object.

The example for last point

 class Foo {
    String f;
 } 

 class Bar {
   String b;
 }

Then problem how to return object Foo and Bar ?

 public Object theProblemMethod() {

      Foo a = new Foo();
          a.foo = "Test";

      Bar b = new Bar();
          b.bar = a.foo;   //The logic where class Foo meet class Bar.

    return ???

 }

The valid implementation

   public Foo createFoo(){ 
      Foo a = new Foo();
          a.foo = "Test";
      return a;
   } 

   public Bar createBar(Foo f) {

      Bar b = new Bar();
          b.bar = f.foo; 
      reutrn b;
   }

Usage

   public void action()  {

           //theProblemMethod(); //This we can not do

          Foo a = createFoo();
          Bar b = createBar(a);
  }

Your actual issue here is one of design. No method should be doing more than one thing: therefore a method that returns two unlike objects is probably bad design. To actually solve this problem, you should break your method into two, separate methods to handle the two different concerns.

However, let us assume you cannot do this. Based on your notes it seems most of your state in the two objects is repeated. You can combine these two by having them inherit from a similar source - but this only solves half your problem. Instead, you can decorate the one with the other:

public class DataExporterPerson {
  private Person person;
  private String program = null; //or any other

  //other getters/setters, esp to get the core 'person' object.
  //note that getters/setters for repeated state should just
  //  pass through to the underlying object:
  public String getName() { person.getName(); } //for example
}

If you absolutely must return two objects, you may do this, but it's hard to test and violates the 'no side effect' principle:

public boolean buildThings(ThingA a, ThingB b) {
  a = <whatever>;
  b = <whatever else>;

  return true;//success!
}

//...
//somewhere else in code
ThingA a = null;
ThingB b = null;
boolean result = buildThings(a, b);
//use a and b here

You could do two different things.

The first have the method signature be public List<Object> getPeople(). This will allow you to do instanceof and figure out which is which.

OR

you could have DataExporterPerson extend Person (or make a new class/interface that both DataExporterPerson and Person extend/implements and use that as the type).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top