2014-10-14 2 views
2

Мне нужно написать объект Java, который используется для хранения результатов расчета. Результаты содержат большое количество полей, которые могут устанавливаться или не устанавливаться, зависит от типа используемого алгоритма. Например:Лучший способ написать 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 

} 

Для различного алгоритма оценки содержание этих свойств может отличаться. Например, если алгоритм равен А, доходность и вероятность будут содержать значение вычисления, остальные из них будут равны нулю; если алгоритм равен B, стандартное отклонение и кривая будут содержать результат, а остальные будут равны нулю и т. д. Правило очень сложное, например, если approcimateValue истинно, часть значения будет переопределено и т. д. Следовательно, все эти свойства должны быть в одном классе, поскольку они логически являются одним результатом.

Альтернативный способ сделать это, чтобы использовать карту

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 
} 

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

Какой будет лучший способ, на ваш взгляд? Есть ли другой лучший способ сделать это?

EDIT: Забыл упомянуть, создавая отдельный класс для каждого расчета. Тип не является вариантом из-за ограничений. Я должен использовать один класс.

+1

Было бы больше смысла создавать специализированные типы результатов для ваших видов расчета. Идея объединения всех типов в один, приводит к таким плохим классам. – Tom

+0

Спасибо за ваш ответ. Я забыл упомянуть, что создание отдельного класса для каждой операции не является опцией из-за ограничения. Я должен использовать один класс. – Kevin

+0

не могли бы вы объяснить, почему это так? – aioobe

ответ

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 
} 

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

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

Прошу извинить мои правки, мне пришлось изменить свой первый пример из-за изменений, сделанных ops в его первоначальном вопросе, который я не заметил до моего первоначального сообщения. – TechTrip

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 
} 

Так что по существу походит ваша идея карты, но с перечислением.

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

} 
+0

Я думаю, что лучше, если опция не установлена ​​извне класса, потому что она должна быть всегда не-null. –

+0

@Amir Moghimi - Спасибо, ты абсолютно прав. В моей спешке, чтобы получить ответ, я автоматически генерировал геттеры и сеттеры. У вариантов не должно быть сеттеров. (Я видел примеры, когда люди используют дополнительные интерфейсы для установки, но важно отметить, что сеттер не использует параметр «Дополнительно как параметр», он использует завернутый тип). Я обновил свой ответ. – TechTrip

Смежные вопросы