如何在Java中实现具有内部依赖性的惰性求值状态类?

Sal*_*ley 8 java design-patterns

我正在编写一个财务计算类,它将有许多setter函数输入,一些私有中间值和一些getter函数作为输出.

  • 私有中间值仅取决于输入值.

  • 输出值(由公共getter访问)仅取决于输入和中间值.

最终你可以将整个事物描绘成一个有点纠结的非循环有向图,其中一侧有一堆输入,最终流向右侧的一堆输出.

实现这个课程的最佳方法是什么.我有一些特殊要求:

  • 在可能的情况下,懒惰评估.当输入改变时,我们现在知道可能需要什么输出.

  • 该类必须易于重新设计,因此某种声明性模型将被优先考虑.

理想情况下,我希望能够说C取决于A和B.如果在A或B改变之后请求C,那么它将知道需要重新计算C,否则C将永远不需要刷新.

我有一个Java模式可以帮助我干净地实现这种计算器吗?

Kru*_*Kru 2

您可以通过创建可重新计算的未来值来构建解决方案。

public class Computation<T> {
   private T value;
   private Set<Computation<?>> usedBy;

   public T getValue(Computation<?> getter) {
     if (usedBy == null) {
       // value was not computed
       value = compute();
       usedBy = new HashSet();
     }
     if (getter != null) {
       // add a dependency
       usedBy.add(getter);
     }
     return value;
   }

   protected T compute() {
     // override when needed a lazily-computed value
     return null;
   }

   public void setValue(T value) {
     // invalidate this value
     invalidate();
     // set the new value
     this.value = value;
     usedBy = new HashSet();
   }

   public void invalidate() {
     if (usedBy != null) {
       for (Computation<?> c : usedBy) {
         c.invalidate();
       }
       usedBy = null;
     }
     value = null;
   }
}

public class Business {
  private Computation<Integer> a = new Computation<Integer>();
  private Computation<Integer> b = new Computation<Integer>();
  private Computation<Integer> c = new Computation<Integer>() {
    public Integer compute() {
      return a.getValue(this) + b.getValue(this);
    }
  };

  public void setA(int v) {
    a.setValue(v);
  }
  public void setB(int v) {
    b.setValue(v);
  }
  public int getC() {
    return c.getValue(null);
  }
}
Run Code Online (Sandbox Code Playgroud)

它完全是懒惰的,并且找出了依赖关系。