質問

My question is a general design question in Java. In typical controller based designs (lets say MVC) , Controllers generally create instances of actions and invoke a method that is implemented from a interface (lets say execute() of Action interface).

Why do we need to create unnecessary objects, why not use static invocation and eliminate the need to implement a interface?

like the example below. Same way as every Java program is expected to have a main() method, every action method is expected to have 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);
    }

}
役に立ちましたか?

解決

Well because Reflection API is much slower than method calling as when using reflection, the compiler can do no optimization whatsoever as it can have no real idea about what you are doing.

By having an interface and multiple concrete classes which implement it, we can have the advantage of polymorphic behavior. Add Factory pattern in the equation, and you can directly work with your interfaces without actually needing to know which concrete class method you are invoking. The added benefit is that the compiler will be able to optimize your code making it run much faster compared to using Reflection API.

As of Java 8, we can have static and instance method implementations in interfaces. Here's a demo:

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 {}

Then there are functional interfaces like:

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

Which allows the creation of different implementations using lambda expressions like:

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

And use like:

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

By the way, if there are lots of objects that need to be created, we use Object Pool pattern or something similar, and if there are lots of similar objects, we use Flyweight Pattern to minimise memory usage while still keeping speed.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top