首页 > 解决方案 > “查看”不可变对象特殊情况的最佳模式

问题描述

假设我有一个不可变对象的层次结构,例如编程语言的表达式


public abstract class Expression {}

public class IntConst extends Expression {
    public final Integer value;
    // ...
}

public class Variable extends Expression {
    public final String name;
    //...
}

public class Sum extends Expression {
    public final Expression child1;
    public final Expression child2;
    //... 
}

public class Product extends Expression {
    public final Expression child1;
    public final Expression child2;
    //... 
}

现在,为了在某些特殊情况下使用此层次结构的对象,我希望对它们有不同的(不可变的)视图。例如,我们可以有一个视图SimpleSum,它有一个equals使a + 0and0 + aa相等的特殊视图,或者一个与and andSimpleProduct做类似事情的视图。a * 11 * aa

我现在实现它的方式是每个视图的静态方法,例如

public static Optional<SimpleSum> viewAsSimpleSum(Expression e) {
    if(isSimpleSum(e)) {
        return Optional.of(new SimpleSum(e));
    } else {
        return Optional.empty();
    }
}

public static boolean isSimpleSum(Expression e) {
    // cascade of "instanceof" or implementation via visitor
}

由于可能有许多不同的视图和算法(例如,映射流中的所有“可见”,而“不可见”不受影响)不依赖于视图的确切类型,我希望有一些通用方法public static <E> Optional<E> viewAs(Expression e)public static <E> boolean isViewableAs(Expression e)如一些助手类。不幸的是,到目前为止我还没有成功(我唯一可行的想法是从视图的构造函数中抛出异常,但我觉得这不够漂亮)。

有没有办法在一般的 Java 中实现这样的东西?

标签: javagenericsdesign-patternsimmutability

解决方案


您可以尝试使用 java 覆盖。

例如:

public class Sum extends Expression {
    public final Expression child1;
    public final Expression child2;

    public Optional calculateSumm () {
      // perform simple calclation
    }
    //... 
 }

public class SimpleSum extends Sum {
    public Optional calculateSumm () {
       // perform simple calculation
    }
}

public class complexSum extends Sum {
   public Optional calculateSumm () {
       // perform complex calculation
   }
}
//--

现在在主类中:

public static void main (String[] args) {
     SimpleSum simple = new SimpleSum();
     ComplexSum complex = new ComplexSum();

    if(isSimpleSum(e)) {

       return simple.calculateSum();

    } else {
       return Optional.empty();
    }
} 


推荐阅读