Лучший шаблон для «просмотра» особых случаев неизменяемых объектов - PullRequest
0 голосов
/ 15 октября 2019

Скажем, у меня есть иерархия неизменяемых объектов, например, выражения языка программирования


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 и 0 + a и a равным, или представление SimpleProduct, которое делает что-то похожее с 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
}

Поскольку потенциально существует много различных представлений и алгоритмов (например, отображение всех)«viewables» в потоке, оставляя «nonviewables» нетронутыми), которые не зависят от точного типа представления, я хотел бы иметь некоторые универсальные методы, такие как public static <E> Optional<E> viewAs(Expression e) или public static <E> boolean isViewableAs(Expression e) в некотором вспомогательном классе. К сожалению, пока мне это не удалось (единственной жизнеспособной идеей, которую я имел, было создание исключения из конструктора представления, но это я не нахожу достаточно симпатичным).

Есть ли способ реализовать что-то вродеэто в общем Java?

1 Ответ

0 голосов
/ 15 октября 2019

Вы можете попробовать использовать переопределение 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();
    }
} 

...