Как создавать динамические операторы IF? отражение? - PullRequest
4 голосов
/ 14 сентября 2011

Возможно ли с помощью отражения создать динамический оператор IF?

Я видел примеры с BeanShell (например: Динамическая проблема вычисления оператора при сравнении строк ), но я хотел бы знать, возможно ли это сделать без BeanShell, и указать на некоторые примеры. адаптироваться к моим потребностям.

В основном у меня есть утверждение вида: оператор B.

A и B могут быть числами (двойными или целыми числами) или строками, но всегда A соответствует типу B. оператор может быть! =, ==,> =,>, <=, <и даже другие, чье поведение может быть определено через собственный класс, еще одна причина, по которой я буду использовать отражение, поскольку я могу взять эту строку и использовать отражение, чтобы вызвать соответствующий метод. </p>

Я хочу (должен) избегать разветвлений "если" и "переключаться", потому что вариаций слишком много, и они будут постоянно меняться в зависимости от вводимых пользователем данных.

Ответы [ 3 ]

3 голосов
/ 14 сентября 2011

Вы можете создать фабрику, которая возвращает правильный оператор для данного ввода.

public class OperatorFactory {
  private static final Map<String, Operator<?>> OPERATORS = new HashMap<String, Operator<?>>();

  static {
    OPERATORS.put("<Number", new LessThanNumOperator());
    OPERATORS.put("==Number", new EqualToNumOperator());
    OPERATORS.put("<String", new LessThanStringOperator());
    ...
  }

  public static Operator<?> getOperator(String someUserSpecifiedOp, Class<?> paramType) {
    String key = someUserSpecifiedOp;
    if (Number.class.isAssignableFrom(paramType)) {
      key += "Number";
    } else if (String.class.isAssignableFrom(paramType)) {
      key += "String";
    }
    return OPERATORS.get(key);
  }
}

public interface Operator<T> {
  public boolean execute(T lhs, T rhs);
}

public class LessThanNumOperator implements Operator<Number> {
  public boolean execute(Number lhs, Number rhs) {
     return  lhs.doubleValue() < rhs.doubleValue();
  }
}

А затем используйте его:

OperatorFactory.getOperator(userDesignatedOperation, lhs.getClass()).execute(lhs, rhs);
1 голос
/ 14 сентября 2011

Отражение не поможет.Reflection дает вам информацию о вашей структуре кода (классы, методы, атрибуты), но не позволяет вам изменять и обновлять существующий код.

Не пытайтесь генерировать новый код, попробуйте вместо добавленияспособ для пользователей изменить поведение вашего приложения в зависимости от их ввода.

Я не знаю точно, что вы пытаетесь сделать.Опубликуйте несколько примеров пользовательского ввода и ожидаемого поведения, чтобы помочь сузить варианты.Но вот несколько вещей, которые могут помочь вам в вашей задаче:

  • Иметь пользовательский интерфейс, который помогает вашему пользователю выбирать время операндов, с текстовыми полями для значений и выпадающим списком дляоператор.Простое решение, но я бы не рекомендовал его, так как оно может усложнить пользовательский интерфейс.
  • Напишите анализатор для ваших выражений.Написание простого синтаксического анализатора для этого очень простого языка (оператор B) должно быть выполнено в разумные сроки.
  • Специфичные для домена языки.Позволяет пользователям вашего приложения писать некоторые сценарии, которые интерпретируются вашим приложением и реагируют определенным образом.Вы можете представить себе DSL, состоящий из простых сравнений, и результаты будут влиять на поведение вашего приложения.Посмотрите на Groovy, это хороший язык для этого варианта использования.
1 голос
/ 14 сентября 2011

Вы могли бы сделать такой интерфейс

public interface MyComparator
{
    public boolean matches(String operator);
    public boolean compare(String a, String b);
}

Тогда вы можете указать, сколько классов вы хотите, чтобы все реализовывали интерфейс, подобный этому

public class MyEquals implements MyComparator
{
    @Override
    public boolean matches(String operator)
    {
    return "==".equals(operator);
    }

    @Override
    public boolean compare(String a, String b)
    {
    return a.equals(b);
    }
}

и загрузите их так:

Class compClass = Class.forName(classname);
MyComparator comp = (MyComparator)compClass.newInstance();

Вы можете подготовить список всех доступных операторов и выполнить итерацию по нему, и даже настроить список операторов в файле свойств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...