Шаблоны проектирования для зависимых вычисляемых свойств в классе?

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

public class AnalysisEntity
{
    public decimal InputA { get; set; }
    public decimal InputB { get; set; }
    public decimal InputC { get; set; }

    public decimal CalculatedValueA
    {
        get { return InputA * InputC; }
    }

    public decimal CalculatedValueB
    {
        get 
        {
            decimal factor = FactorGenerator.ExpensiveOperation();
            return CalculatedValueA / factor; 
        }
    }

    public decimal CalculatedValueC
    {
        get { return InputA * InputB; }
    }

    public decimal CalculatedValueD
    {
        get { return (CalculatedValueA * InputB) / CalculatedValueB; }
    }

    public decimal CalculatedValueE
    {
        get { return CalculatedValueD / aConstant; }
    }
}

Однако это решение оставляет мне следующие проблемы:

  1. Это неэффективно, поскольку некоторые из вычислений (некоторые из которых длительны) многократно вызывается.
  2. Трудно проводить единичное тестирование отдельных вычислений изолированно без предоставления всех необходимых входных данных, чтобы все зависимые вычисления работали в первую очередь.
  3. Трудно эффективно извлечь из персистентности (я использую NHibernate), потому что даже несмотря на то, что рассчитанные данные могут быть сохранены в базе данных, они не извлекаются, а вместо этого пересчитываются при чтении объекта.
  4. Трудно добавлять вычисления, поскольку модульные тесты становятся все больше и больше с необходимыми входными данными.

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

Какие шаблоны проектирования и структуру классов мне следует использовать для решения вышеуказанных проблем?

Спасибо

]
6
задан Forever Refactoring 26 October 2010 в 23:18
поделиться