mardi 15 octobre 2019

Best pattern to "view" special cases of immutable Objects

Say I have a hierarchy of immutable Objects like e.g. the the expressions of a programming language


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;
    //... 
}

Now, in order to work with the objects of this hierarchy in some special cases, I want to have different (immutable) views on them. For example we could have a view SimpleSum which has a special equals that makes a + 0 and 0 + a and a equal or a view SimpleProduct that does something similar with a * 1 and 1 * a and a.

The way I have implemented it right now are static methods for each view, e.g.

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
}

Since there are potentially many different views and algorithms (e.g. a mapping all "viewables" in a stream while leaving the "nonviewables" untouched) that are not dependent on the exact type of view, I would like to have some generic methods like public static <E> Optional<E> viewAs(Expression e) or public static <E> boolean isViewableAs(Expression e) in some helper class. Unfortunately I have not succeeded so far (the only viable idea I had was throwing an exception from the constructor of the view, but this I don't find sufficiently pretty).

Is there a way to implement something like this in generically Java?

Aucun commentaire:

Enregistrer un commentaire