Java - 从一个方法返回多个对象类型的最佳方式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18151540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java - Best way to return multiple object types from a method
提问by Catfish
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>
.
在我的 DAO 中,我有一种方法可以构建 2 个不同的对象,并且我想返回这两个对象,但我不确定最好的方法是什么。我看过 using ? extends myObject
,创建另一个类来保存我想要返回的两个对象,然后只使用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.
长话短说,为什么我需要这些类似的对象是在屏幕上显示 1 个,另一个与 primefaces dataexporter 一起使用,据我所知,它不处理对象中的列表。
Class Person
班级人物
public class Person() {
firstName = null;
lastName = null;
List<Programs> programs = new ArrayList<Programs>();
// Getters and setters
}
Class DataExporterPerson
类 DataExporterPerson
public class DataExporterPerson() {
firstName = null;
lastName = null;
String program = null;
// Getters and setters
}
DAO method:
DAO方法:
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.
现在我明白我可以很容易地创建另一个对象,如下所示,但这似乎是一种低效的做事方式,因为我基本上创建一个对象只是为了从 1 个方法返回。
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.
我尝试在 1 个方法中返回 2 个对象的原因是,这是一个 DAO 方法,它查询数据库并根据查询中的数据构建 2 个对象。我不想将其分解为 2 种方法,因为如果不需要,我不想两次查询数据库。
采纳答案by Pete B.
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.
您可以拥有Person
和DataExporterPerson
扩展类似AbstractPerson
. 但是,既然你还没有这样做,那么做继承可能是不合适的。
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.
我认为是 Effective C++ 谈到了包含比继承更好。IIRC 陈述的原因是包含比继承更松散耦合。
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.
在这里,您将拥有一个同时包含Person
和的对象 DataExporterPerson
。您的方法将为该联合类型对象填充其中一个,通过查看哪个为空,您将知道您实际拥有哪个。
public class DBPersonUnion {
private Person person = null;
private DataExporterPerson dataExporterPerson = null;
//getters and setters.
}
回答by Brinnis
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.
第一个有方法签名是public List<Object> getPeople()
。这将允许你做instanceof
并弄清楚哪个是哪个。
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).
您可以DataExporterPerson
扩展Person
(或创建一个新的类/接口,DataExporterPerson
并且Person
扩展/实现并将其用作类型)。
回答by Damian Leszczyński - Vash
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 ?
那么问题如何返回对象 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 ???
}
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);
}
回答by Nathaniel Ford
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