我必须编写一个用于保存计算结果的Java对象。结果包含大量可能设置或不设置的字段取决于所使用的算法类型。例如:
class EquityValuationResult {
private ValuationAlgorithm algorithm;
private int yield;
private double curve;
private double meanValue;
private double probability;
private int standardDeviation;
private boolean approximateValue;
......
//Getter and Setters
}
对于不同的ValuationAlgorithm,这些属性的内容可能不同。例如,如果算法是A,则yield和probability将包含计算值,其余的将为null;如果算法是B,则standardDeviation和curve将包含结果,其余的将为null等。规则非常复杂,例如,如果approcimateValue为true,则某些值将被覆盖等。因此,所有这些属性必须属于一个类,因为它们在逻辑上是一个结果。
另一种方法是使用Map
class EquityValuationResult {
private final String YIELD = "yield";
private final String CURVE = "curve";
........
private ValuationAlgorithm algorithm;
private final Map<String, Object> result = new HashMap<String, Object>();
// Getter and Setters
}
但是,如果我这样做,getter和setter必须将值从Object转换为相应的数据类型。我还必须定义这些常量并将它们用作地图的关键,这看起来太麻烦了。
您认为哪种方式更好?还有其他更好的方法吗?
编辑:忘记提及,由于约束,为每个calculateType创建单独的类不是一个选项。我必须使用一个班级。
答案 0 :(得分:3)
@Joel发表评论,引发了一个灯泡。 Java 8有一个可选项,仅用于此目的。
要了解如何应用这个例子,你可以在这里阅读它,也许这最有效。
http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html
例如:
import java.util.Optional;
public class Result {
final CalculationType calculationType;
private Optional<Integer> yield = Optional.empty();
private Optional<Double> curve = Optional.empty();
private Optional<Double> meanValue = Optional.empty();
private Optional<Double> probability = Optional.empty();
private Optional<Integer> standardDeviation = Optional.empty();
public Result(CalculationType calculationType) {
this.calculationType = calculationType;
}
public CalculationType getCalculationType() {
return calculationType;
}
public Optional<Integer> getYield() {
return yield;
}
public Optional<Double> getCurve() {
return curve;
}
public Optional<Double> getMeanValue() {
return meanValue;
}
public Optional<Double> getProbability() {
return probability;
}
public Optional<Integer> getStandardDeviation() {
return standardDeviation;
}
}
答案 1 :(得分:1)
也许一个选项是创建一个表示变量名的枚举类:
public enum ResultKey {
YIELD,
CURVE,
MEAN_VALUE,
...
// you can add getValue(Map<ResultKey, Object> map) and
// setValue(Map<ResultKey, Object> map, Object value) methods
}
然后在你的结果类中有一张地图:
class EquityValuationResult {
private ValuationAlgorithm algorithm;
private Map<ResultKey, Object> result = new HashMap<>();
// Getter and Setters
}
所以它基本上就像你的地图想法,但有一个枚举。
答案 2 :(得分:0)
如果允许您创建帮助器或其他内容,请忘记地图示例。在这个限制下,我可能会将枚举作为帮助器/类型来编写,以识别并可能使用映射器来保存基于类型的顺序。
作为结果类中的辅助方法,可能是:
public double[] getCalcValues(){
switch (calculationType){
case A:
// do something
return null;
case B:
// do something
return null;
default:
throw new RuntimeException("Not Really Possible");
}
}
由于CaclulationType的枚举类型,这有望成为可能。 例如:
public enum CalculationType {
A("A"), B("B");
final String calcType;
private CalculationType(String calcType) {
this.calcType = calcType;
}
// ... other enum stuff
}
在这种情况下,我可以将枚举最终用于实例化,并使用静态辅助方法进行cal值提取,并故意将getter从主类中删除,除非有人拉出空值即可。如果你不想在其他地方需要的话,我会留下一个enum的getter,如果没有,那么我想我也会把它留下来。
public class Result {
final CalculationType calculationType;
private int yield;
private double curve;
private double meanValue;
private double probability;
private int standardDeviation;
public Result(CalculationType calculationType) {
this.calculationType = calculationType;
}
public CalculationType getCalculationType() {
return calculationType;
}
public double[] getCalcValues(){
switch (calculationType){
case A:
// do something
return null;
case B:
// do something
return null;
default:
throw new RuntimeException("Not Really Possible");
}
}
// Only include setters below, force users to use getCalcValues as an extraction class
}