java - “查看”不可变对象特殊情况的最佳模式
问题描述
假设我有一个不可变对象的层次结构,例如编程语言的表达式
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 + 0
and0 + a
和a
相等的特殊视图,或者一个与and andSimpleProduct
做类似事情的视图。a * 1
1 * 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 <E> Optional<E> viewAs(Expression e)
,public static <E> boolean isViewableAs(Expression e)
如一些助手类。不幸的是,到目前为止我还没有成功(我唯一可行的想法是从视图的构造函数中抛出异常,但我觉得这不够漂亮)。
有没有办法在一般的 Java 中实现这样的东西?
解决方案
您可以尝试使用 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();
}
}
推荐阅读
- python - 使用opencv和python制作虚拟键盘时出现意外输出
- javascript - 将外部变量传递给 Axios.get().then() 调用
- sql-server - 将 CSV 文件添加为链接的服务器连接
- json - 使用 bash 删除 jsonpath 模板中的逗号
- reactjs - 在反应 keplerGL 应用程序中添加网格或 hexbin 层时出错
- r - 使用正则表达式删除多个实例,但不删除实例之间的文本
- ios - 从单独的 Swift 框架/模块中使用 Apple Pay
- sql - 在基于条件的递归 SQL 查询中返回真/假
- mysql - 在重复的情况下更新。在第一次的情况下插入
- javascript - 打字稿:为枚举中的键添加类型