2013-08-09 12 views
8

Nel mio DAO ho un metodo in cui creo 2 oggetti diversi e voglio restituire entrambi quegli oggetti, ma non sono sicuro di quale sia il modo migliore per fallo. Ho guardato usando ? extends myObject, creando un'altra classe che contiene entrambi i miei oggetti che voglio restituire, e usando semplicemente List<Object>.Java: il modo migliore per restituire più tipi di oggetto da un metodo

In breve, perché ho bisogno di questi oggetti simili è quello di visualizzare 1 sullo schermo e l'altro da usare con primefaces dataexporter che non gestisce gli elenchi in un oggetto per quanto ne so.

Classe persona

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

    // Getters and setters 
} 

Classe DataExporterPerson

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

    // Getters and setters 
} 

metodo DAO:

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

    // build both objects 

    return ????? 
} 

ora ho capito che posso creare facilmente un altro oggetto come quella qui sotto, ma che sembra come un modo inefficiente di fare le cose perché fondamentalmente sto creando un oggetto solo per tornare da 1 meth od.

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

Qual è il modo migliore per gestire questo scenario?

EDIT

La ragione per cui sto cercando di tornare 2 oggetti in 1 metodo è perché questo è un metodo DAO che interroga il database e costruisce 2 oggetti in base ai dati nella query. Non voglio suddividerlo in 2 metodi perché non voglio interrogare il db due volte se non ne ho bisogno.

+1

Perché 'DataExporterPerson' non' estende Person'? Quindi potresti usare una 'Collezione '. –

+1

In genere è una cattiva idea che un singolo metodo faccia due cose. Puoi chiarire perché l'unico metodo * richiede * due valori di ritorno? –

+0

Potrebbe non funzionare due cose; potrebbe fare una cosa e restituire una 2-tupla. –

risposta

8

È possibile gestirlo tramite ereditarietà o contenimento.

È possibile avere Person e DataExporterPerson estendere qualcosa come AbstractPerson. Tuttavia, poiché non lo hai già fatto, è probabilmente inappropriato fare ereditarietà.

Penso che sia stato un efficace C++ a parlare di come il contenimento sia migliore dell'ereditarietà. IIRC la ragione affermata è che il contenimento è più strettamente accoppiato dell'ereditarietà.

Qui si avrebbe un oggetto che contiene sia Person sia DataExporterPerson. Il tuo metodo popolerebbe uno di quelli per questo oggetto di tipo union, e vedendo quale è nullo sapresti quale effettivamente hai.

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

    //getters and setters. 
} 
+0

Tack su uno o due metodi di supporto o un'enumerazione per questi tipi di 'unione' con più di alcune opzioni possibili. È effettivamente un tipo di dati algebrici non valido. –

+0

Anche se ho 'Perso'n e' DataExporterPerso'n estendono 'AbstractPerson', come mi sarebbe utile perché avrei ancora bisogno di restituire sia 'Person' che' DataExporterPerson' dal mio metodo DAO. – Catfish

-2

Si potrebbero fare due cose diverse.

Il primo ha la firma del metodo public List<Object> getPeople(). Questo ti permetterà di fare instanceof e capire quale è quale.

O

si potrebbe avere DataExporterPerson estendere Person (o fare una nuova classe/interfaccia che sia DataExporterPerson e Person estendono/utensili e l'uso che come tipo).

5

Se il metodo ha bisogno di restituire due tipi diversi questo è un suggerimento che ci sia qualcosa di sbagliato con l'architettura o la logica metodo.

Cosa si può fare?

  • Creare una classe che logicamente unire gli elementi,
  • Introdurre interfaccia comune che, sia la classe attuerà,
  • implementare due metodi ritorno pugno con oggetto, che secondo l'uso di un parametro e riportare il secondo oggetto .

L'esempio per ultimo punto

class Foo { 
    String f; 
} 

class Bar { 
    String b; 
} 

Poi problema come restituire oggetto Foo e 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 ??? 

} 

La valida implementazione

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

Uso

public void action() { 

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

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

puoi modificare il tuo punto III? Non è chiaro. – Algorithmist

+0

@Algorithmist, spero che ora mi chiarisca. –

2

vostro problema effettivo qui è uno del disegno. Nessun metodo dovrebbe fare più di una cosa: quindi un metodo che restituisce due oggetti diversi è probabilmente una cattiva progettazione. Per risolvere effettivamente questo problema, dovresti suddividere il tuo metodo in due metodi separati per gestire i due diversi problemi.

Tuttavia, supponiamo di non poterlo fare. Sulla base delle tue note sembra che la maggior parte del tuo stato nei due oggetti sia ripetuta. È possibile combinare questi due ereditandoli da una fonte simile, ma questo risolve solo metà del problema. Invece, è possibile decorare l'uno con l'altro:

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 
} 

Se è assolutamente necessario restituire due oggetti, si può fare questo, ma è difficile per testare e viola la 'nessun effetto collaterale' principio:

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 
+0

Il tuo secondo esempio non funzionerà perché i miei oggetti si trovano in una classe diversa. Il mio 'ThingA' e' ThingB' sono nel mio backing bean, e il mio metodo è nel mio DAO. – Catfish

+0

Quindi stai ponendo una domanda completamente diversa da "come posso restituire due oggetti da un metodo?'. –

+0

Non proprio. Ho classA.methodA che chiama ClassB.methodA, che sto cercando di restituire più oggetti da ClassB.method. – Catfish

Problemi correlati