【问题标题】:Best pattern to "view" special cases of immutable Objects“查看”不可变对象特殊情况的最佳模式
【发布时间】:2019-10-15 10:22:56
【问题描述】:

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


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 + 00 + aa 相等,或者一个视图SimpleProduct,它与a * 11 * a 做类似的事情,并且a.

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

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 &lt;E&gt; Optional&lt;E&gt; viewAs(Expression e)public static &lt;E&gt; boolean isViewableAs(Expression e)。不幸的是,到目前为止我还没有成功(我唯一可行的想法是从视图的构造函数中抛出异常,但我觉得这不够漂亮)。

有没有办法在一般的 Java 中实现类似的东西?

【问题讨论】:

    标签: java generics design-patterns immutability


    【解决方案1】:

    您可以尝试使用 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();
        }
    } 
    

    【讨论】:

      猜你喜欢
      • 2016-12-13
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 2017-06-15
      • 2016-10-23
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多