2013-08-09 58 views
8

Trong DAO của tôi, tôi có phương thức mà tôi xây dựng 2 đối tượng khác nhau và tôi muốn trả về cả hai đối tượng đó, nhưng tôi không chắc cách tốt nhất là làm đi. Tôi đã xem xét sử dụng ? extends myObject, tạo một lớp khác chứa cả hai đối tượng của tôi mà tôi muốn trả về và chỉ sử dụng List<Object>.Java - Cách tốt nhất để trả về nhiều kiểu đối tượng từ một phương thức

Câu chuyện dài ngắn về lý do tại sao tôi cần các đối tượng tương tự này để hiển thị 1 trên màn hình và mặt kia để sử dụng với dữ liệu thủ công không xử lý danh sách trong đối tượng theo như tôi biết.

Lớp Person

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

    // Getters and setters 
} 

Lớp DataExporterPerson

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

    // Getters and setters 
} 

phương pháp DAO:

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

    // build both objects 

    return ????? 
} 

Bây giờ tôi hiểu tôi có thể rất dễ dàng tạo ra một đối tượng như hình dưới đây, nhưng điều đó dường như một cách không hiệu quả để làm mọi thứ vì tôi cơ bản tạo ra một vật thể chỉ để trở về từ 1 meth od.

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

Cách tốt nhất để xử lý trường hợp này là gì?

EDIT

Lý do mà tôi đang cố gắng để trở lại 2 đối tượng trong 1 phương pháp là bởi vì đây là một phương pháp DAO rằng truy vấn cơ sở dữ liệu và xây dựng 2 đối tượng dựa trên các dữ liệu trong truy vấn. Tôi không muốn chia nó thành 2 phương pháp vì tôi không muốn truy vấn db hai lần nếu tôi không cần.

+1

Tại sao 'DataExporterPerson' không' mở rộng Person'? Sau đó, bạn có thể sử dụng một 'Bộ sưu tập '. –

+1

Nói chung một ý tưởng không tốt cho một phương pháp duy nhất là làm hai việc. Bạn có thể làm sáng tỏ tại sao một phương thức * yêu cầu * hai giá trị trả về? –

+0

Có thể không làm hai việc; nó có thể làm một điều và trả về 2-tuple. –

Trả lời

8

Bạn có thể xử lý việc này thông qua kế thừa hoặc ngăn chặn.

Bạn có thể có PersonDataExporterPerson mở rộng một cái gì đó như AbstractPerson. Tuy nhiên, vì bạn chưa làm như vậy, có lẽ nó không phù hợp để làm thừa kế.

Tôi nghĩ rằng đó là hiệu quả C++ mà nói về cách ngăn chặn là tốt hơn so với thừa kế. IIRC lý do được nêu là ngăn chặn được kết hợp lỏng lẻo hơn thừa kế.

Tại đây bạn sẽ có đối tượng chứa cả hai số PersonDataExporterPerson. Phương pháp của bạn sẽ điền một trong những đối tượng kiểu liên kết này, và bằng cách xem cái nào là null, bạn sẽ biết cái nào bạn thực sự có.

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

    //getters and setters. 
} 
+0

Tack vào một hoặc hai phương pháp trợ giúp hoặc một kiểu liệt kê cho các loại 'công đoàn' này với nhiều hơn một vài tùy chọn có thể. Đó là một loại dữ liệu đại số lỏng lẻo. –

+0

Thậm chí nếu tôi có 'Perso'n và' DataExporterPerso'n mở rộng 'AbstractPerson', nó sẽ giúp tôi như thế nào vì tôi vẫn cần trả về' Person' và 'DataExporterPerson' từ phương thức DAO của tôi. – Catfish

-2

Bạn có thể làm hai việc khác nhau.

Chữ ký đầu tiên có chữ ký phương thức là public List<Object> getPeople(). Điều này sẽ cho phép bạn làm instanceof và tìm ra cái nào.

HOẶC

bạn có thể có DataExporterPerson mở rộng Person (hoặc thực hiện một lớp/giao diện mới mà cả hai DataExporterPersonPerson mở rộng/dụng cụ và sử dụng như các loại).

5

Nếu phương pháp của bạn cần trả về hai loại khác nhau, đây là gợi ý rằng có gì đó sai với kiến ​​trúc hoặc logic phương pháp của bạn.

Bạn có thể làm gì?

  • Tạo một lớp hợp lý sẽ tham gia vào các yếu tố,
  • giới thiệu giao diện phổ biến mà, cả lớp sẽ thực hiện,
  • Thực hiện hai phương pháp trở lại nắm tay với đối tượng, rằng việc sử dụng thứ hai một tham số và trả lại đối tượng thứ hai .

Ví dụ cho điểm cuối cùng

class Foo { 
    String f; 
} 

class Bar { 
    String b; 
} 

Sau đó, vấn đề làm thế nào để trở về đối tượng Foo và 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 ??? 

} 

Việc thực hiện hợp lệ

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

Cách sử dụng

public void action() { 

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

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

bạn có thể vui lòng chỉnh sửa điểm III của bạn.Đó không rõ ràng. – Algorithmist

+0

@Algorithmist, tôi hy vọng rằng bây giờ tôi rõ ràng. –

2

vấn đề thực tế của bạn ở đây là một trong những thiết kế. Không có phương thức nào nên làm nhiều thứ: do đó một phương thức trả về hai đối tượng không giống như có lẽ là thiết kế tồi. Để thực sự giải quyết vấn đề này, bạn nên chia phương thức của mình thành hai, các phương thức riêng biệt để xử lý hai mối quan tâm khác nhau.

Tuy nhiên, giả sử bạn không thể thực hiện việc này. Dựa trên ghi chú của bạn có vẻ như hầu hết trạng thái của bạn trong hai đối tượng được lặp lại. Bạn có thể kết hợp hai thứ này bằng cách để chúng kế thừa từ một nguồn tương tự - nhưng điều này chỉ giải quyết được một nửa vấn đề của bạn. Thay vào đó, bạn có thể trang trí một với người kia:

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 
} 

Nếu bạn hoàn toàn phải trả lại hai đối tượng, bạn có thể làm điều này, nhưng thật khó để kiểm tra và vi phạm 'không tác dụng phụ' nguyên tắc:

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

Ví dụ thứ hai của bạn sẽ không hoạt động vì các đối tượng của tôi nằm trong một lớp khác. 'ThingA' và' ThingB' của tôi nằm trong bean sao lưu của tôi, và phương pháp của tôi là trong DAO của tôi. – Catfish

+0

Sau đó, bạn hỏi một câu hỏi khác hoàn toàn từ 'làm cách nào để trả về hai đối tượng từ một phương pháp?'. –

+0

Không thực sự. Tôi có classA.methodA gọi ClassB.methodA, mà tôi đang cố gắng trả lại nhiều đối tượng từ ClassB.method. – Catfish

Các vấn đề liên quan