Использование основанного на отражении статического вызова вместо интерфейсов

1

Мой вопрос - это общий вопрос дизайна на Java. В типичных конструкциях на базе контроллера (например, MVC) контроллеры обычно создают экземпляры действий и вызывают метод, реализованный из интерфейса (скажем, execute() интерфейса Action).

Почему нам нужно создавать ненужные объекты, почему бы не использовать статический вызов и исключить необходимость реализации интерфейса?

как пример ниже. Точно так же, как ожидается, что каждая программа Java будет иметь метод main(), ожидается, что каждый метод действия будет иметь execute()

class MyActionClass {
    public static void execute() {
        System.out.println("Hello from execute()!!");
    }
}

public class StaticTest {

    /**
     * @param args
     * @throws ClassNotFoundException
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static void main(String[] args) throws ClassNotFoundException,
                        NoSuchMethodException, SecurityException, IllegalAccessException,
                        IllegalArgumentException, InvocationTargetException {
        Class<?> clazz = Class.forName("MyActionClass");
        Method method = clazz.getMethod("execute");
        method.invoke(null);
    }

}
Теги:
model-view-controller
design
interface
static-methods

1 ответ

2
Лучший ответ

Хорошо, потому что API Reflection намного медленнее, чем вызов метода, как при использовании рефлексии, компилятор вообще не может оптимизировать, поскольку он не может иметь никакого реального представления о том, что вы делаете.

Имея интерфейс и несколько конкретных классов, которые его реализуют, мы можем иметь преимущество полиморфного поведения. Добавьте шаблон Factory в уравнение, и вы можете напрямую работать с вашими интерфейсами без необходимости знать, какой конкретный метод класса вы вызываете. Дополнительным преимуществом является то, что компилятор сможет оптимизировать ваш код, заставляя его работать намного быстрее по сравнению с использованием Reflection API.

Начиная с Java 8, мы можем иметь статические и реализации методов экземпляра в интерфейсах. Вот демо:

public class InterfaceDemo
{
  public static void main(String... args)
  {
    XYZ.executeStatic("Hello");

    XYZ object = new Implementer();
    object.executeInstance("Message");
  }
}

interface XYZ
{
  static void executeStatic(String message)
  {
    System.out.println("Static: " + message);
  }

  default void executeInstance(String message)
  {
    System.out.println("Instance: " + message);
  }
}

class Implementer implements XYZ {}

Тогда есть функциональные интерфейсы, такие как:

@FunctionalInterface
public interface Returnable<T>
{
  public T value();
}

Это позволяет создавать различные реализации с использованием лямбда-выражений, таких как:

Returnable<Integer> integerReturnable = () -> 42;
Returnable<String> stringReturnable = () -> "Hello";

И используйте как:

System.out.println(integerReturnable.value()); // Prints 42
System.out.println(stringReturnable.value()); // Prints Hello

Кстати, если есть много объектов, которые нужно создать, мы используем шаблон пула объектов или что-то подобное, и если есть много похожих объектов, мы используем шаблон Flyweight, чтобы минимизировать использование памяти, сохраняя при этом скорость.

  • 0
    Согласился с необходимостью фабричного образца, когда мы создаем множество объектов. Но мой вопрос здесь заключается в том, что эти классы действий, как правило, не имеют локального хранилища, все, что потребитель хочет сделать, - это выполнить какое-то действие, почему потребители должны создавать экземпляры объектов, когда они могут использовать статический вызов? Я полагаю, что все эти фреймворки уже используют рефлексию для создания соответствующих классов действий, поэтому нет сомнений, что рефлексия медленная.
  • 0
    Ну, о какой структуре вы особенно говорите? Причина в архитектуре MVC, модели и представления создаются не отражением, а созданием объекта и затем используются с использованием обычных вызовов методов. Фреймворк может использовать Reflection для создания экземпляров методов на объектах, но есть много других более простых и быстрых способов обработки таких ситуаций. Отражение медленное по сравнению с прямым вызовом метода и созданием объекта, поэтому общий консенсус не склонен к его использованию. Reflection API имеет свои преимущества, но не особенно в этой ситуации.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню