How to add similar functionality to multiple methods in java?

I have many methods for logging, for example logSomeAction, logAnotherActionetc.

Now I want all these methods to pause after printing messages (Thread.sleep).

If I do it manually, I would do something like this:

//before:
public static void logSomeAction () {
   System.out.println (msg(SOME_ACTION));
}

//after:
public static void logSomeAction () {
   System.out.println (msg(SOME_ACTION));
   try {
      Thread.sleep (2000);
   } catch (InterruptedException ignored) { }
}

I remember that Java has proxy classes and some other magic tools. Is there a way to avoid copy-n-pasting N sleeping blocks into N registration methods?

+3
source share
6 answers

You can use Aspects to add additional “orthogonal” functions to your methods.

, , . , , , , - , .

+7

, Aspect Oriented Programming. Spring AOP AspectJ.

+2

OP , java-. - java-- . - :

public interface SomeActionLogger
{
   void logSomeAction();
   void logSomeOtherAction();
   // etc..
}

public class SystemOutActionLogger implements SomeActionLogger
{
   public void logSomeAction () {
      System.out.println (msg(SOME_ACTION));
   }
}

Java-- SomeActionLogger

class DelayAfterInvocationHandler implements InvocationHandler
{
    private Object delegate;
    private int duration;

    DelayAfterInvocationHandler(Object delegate, int duration)
    {
        this.delegate = delegate;
        this.duration = duration;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        Object returnValue = method.invoke(delegate, args);
        Thread.sleep(duration);
        // you may want to catch InterruptedEception
        return returnValue;
    }
}

- -, , , .

public ActionLogger addDelay(SomeActionLogger logger, int delay)
{
    return (ActionLogger)Proxy.newProxyInstance(
       impl.getClass().getClassLoader(),
       new Class[] { SomeActionLogger.class }, 
       new DelayAfterInvocationHandler(logger, delay));
}

,

SomeActionLogger log = addDelay(new SystemOutActionLogger(), 2000);

, DelayInvocationHandler - . :

public <T> T addDelay(T delegate, int delay, Class<T> interfaceType)
{
    return (T)Proxy.newProxyInstance(
       delegate.getClass().getClassLoader(),
       new Class[] { type }, 
       new DelayAfterInvocationHandler(delegate, delay));
}
+1

SleepFor , try ... catch , ?

0

System.out.println(msg (SOME_ACTION)); printAndWait (SOME_ACTION); .

public static void printAndWait(Object someAction) {
   System.out.println (msg(someAction)); 
   try { 
      Thread.sleep (2000); 
   } catch (InterruptedException ignored) {
      Thread.currentThread.interrupt();
   } 
} 

Thus, the code appears once, and you can easily change it in one place.

0
source

Replace all your methods with logSomeAction()one method logAction(Action a). This way, when you add more actions in the future, you will not repeat your code to process the action log and sleep thread.

0
source

Source: https://habr.com/ru/post/1749728/


All Articles