Java-лучший способ вернуть несколько типов объектов из метода [closed]

в моем DAO у меня есть метод, где я строю 2 разных объекта, и я хочу вернуть оба этих объекта, но я не уверен, что лучший способ это сделать. Я посмотрел на использование ? extends myObject, создавая другой класс, который содержит оба моих объекта, которые я хочу вернуть, и просто используя List<Object>.

короче говоря, почему мне нужны эти подобные объекты, чтобы отобразить 1 на экране, а другой использовать с primefaces dataexporter, который не обрабатывает списки в объекте, насколько я в курсе.

Человек

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

  // Getters and setters
}

Класс DataExporterPerson

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

  // Getters and setters
}

метод DAO:

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

  // build both objects

  return ?????
}

теперь я понимаю, что могу очень легко создать другой объект, подобный приведенному ниже, но это кажется неэффективным способом делать вещи, потому что я в основном создаю объект только для возврата из 1 метода.

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

каков наилучший способ справиться с этим сценарием?

редактировать

в причина, по которой я пытаюсь вернуть 2 объекта в 1 Метод, заключается в том, что это метод DAO, который запрашивает базу данных и строит 2 объекта на основе данных в запросе. Я не хочу разбивать его на 2 метода, потому что я не хочу запрашивать БД дважды, если мне это не нужно.

4 ответов


вы можете либо справиться с этим через наследование, либо сдерживание.

вы можете Person и DataExporterPerson продлить что-то вроде AbstractPerson. Однако, поскольку вы еще этого не сделали, то, вероятно, нецелесообразно делать наследование.

Я думаю, что это был эффективный C++, который рассказал о том, как сдерживание лучше, чем наследование. IIRC указанная причина заключается в том, что сдерживание более слабо связано, чем наследование.

здесь у вас будет объект который содержит оба Person и DataExporterPerson. Ваш метод заполнит один из них для этого объекта типа объединения, и, увидев, какой из них равен null, вы узнаете, какой из них у вас есть.

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

  //getters and setters.
}

если ваш метод должен возвращать два разных типа, это намек на то, что с вашей архитектурой или логикой метода что-то не так.

что можно сделать ?

  • создайте класс, который логически присоединится к элементам,
  • ввести общий интерфейс, который оба класса будут реализовывать,
  • реализуйте два метода fist return с object, что второй используйте параметр и верните второй объект.

в пример для последнего пункта

 class Foo {
    String f;
 } 

 class Bar {
   String b;
 }

тогда проблема, как вернуть объект Foo и 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 ???

 }

действительной реализации

   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;
   }

использование

   public void action()  {

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

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

ваша фактическая проблема здесь-одна из дизайна. Ни один метод не должен делать более одной вещи: поэтому метод, который возвращает два непохожих объекта, вероятно, плохой дизайн. На самом деле решить эту проблему, вы должны разбить свой метод на два отдельных метода для обработки двух разных проблем.

однако предположим, что вы не можете этого сделать. На основе ваших заметок кажется, что большая часть вашего состояния в двух объектах повторяется. Вы можете объединить эти два, они наследуют от похожие источника - но это решает только половину проблемы. Вместо этого вы можете украсить один с другим:

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
}

Если вы абсолютно должны вернуть два объекта, вы можете сделать это, но это трудно проверить и нарушает принцип "без побочных эффектов":

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

вы могли бы сделать две разные вещи.

первые имеют подпись метода быть public List<Object> getPeople(). Это позволит вам сделать instanceof и выяснить, что есть что.

или

вы могли бы DataExporterPerson расширения Person (или сделать новый класс/интерфейс, который как DataExporterPerson и Person extend / implements и использовать это в качестве типа).