使用反射或面向方面编程?

ora*_*rak 1 java

我在java中开发了一个包含大约30个操作的Web服务.除2-3行外,每个操作都具有完全相同的代码.以下是代码草图

public Response operation1(String arg1, String arg2)
{
   initialze(); // this line will be different for each operation with different arguments
   authorizeSession();
   Response res;

   if (authorized)
   {
       try 
       {
          Object result = callMethod1(arg1, arg2); // This line is different for each operation
          res = Response.ok(result).build();
       }
       catch( MultipleExceptions ex)
       {
          res = handleExceptions();
       }
       finally
       {
           logInDatabase();
       }

   }
   return res;
}
Run Code Online (Sandbox Code Playgroud)

我应该遵循什么方法,以便我不必在每个操作中编写相同的代码?

  1. 我应该使用反射吗?
  2. 我听说过面向方面编程......可以在这里使用AOP吗?
  3. 我应该使用普通的旧开关案例语句和一种方法来决定根据操作调用哪种方法?

JB *_*zet 8

这看起来像模板方法模式的一个很好的候选者.定义一个包含main方法(final)的抽象类,该方法将特定部分委托给受保护的抽象方法.

在Web服务的每个方法中,实例化此抽象类的子类,该子类仅覆盖两个特定的抽象方法,并调用此子类实例的main方法.

public abstract class Operation {
    public final Response answer(String arg1, String arg2) {
        authorizeSession();
        Response res;

        if (authorized) {
            try {
                Object result = executeSpecificPart(arg1, arg2);
                res = Response.ok(result).build();
            }
            catch (MultipleExceptions ex) {
                res = handleExceptions();
            }
            finally {
                logInDatabase();
            }
        }

        return res;
    }

    protected abstract Object executeSpecificPart(String arg1, String arg2);
}

...

    public Response operation1(final String arg1, final String arg2) {
        initialize();
        Operation op1 = new Operation() {
            protected Object executeSpecificPart(String arg1, String arg2) {
                ...
            }
        };
        return op1.answer();
    }
Run Code Online (Sandbox Code Playgroud)


Tom*_*icz 5

模板方法模式和/或策略模式

每种方法都会创建自己的Callable实例并将其传递给一个通用run()方法:

public Response operation1(String arg1, String arg2)
{
    initialze(); // this line will be different for each operation with different arguments
    return run(new Callable<Object> {
        public Object call() {
            return callMethod1(arg1, arg2); // This line is different for each operation
        }
    });
}

private Response run(Callable<Object> method) {
   authorizeSession();
   if (authorized)
   {
       try 
       {
          Object result = method.call();
          return Response.ok(result).build();
       }
       catch( MultipleExceptions ex)
       {
          return handleExceptions();
       }
       finally
       {
           logInDatabase();
       }
   }
   return null;
}
Run Code Online (Sandbox Code Playgroud)

如果 Java 有 lambda,那么读写会容易得多。

奥普

面向方面的编程在这里不是最好的工具,因为您必须拦截方法内的某些内容。当您需要在方法之前或之后调用某些内容(或者当它抛出某些内容时),AOP 最适合。这同样适用于反射。

然而,AOP 将显着改善错误处理。然后您的代码可以简化为:

public Response operation1(String arg1, String arg2)
    {
    initialze(); // this line will be different for each operation with different arguments
    authorizeSession();

    if (authorized)
    {
        Object result = callMethod1(arg1, arg2); // This line is different for each operation
        return Response.ok(result).build();
    }
    return null;
    }
Run Code Online (Sandbox Code Playgroud)

和 的捕获MultipleExceptionsfinally阻止可以放置在AfterThrowingAfter建议中。