How to efficiently implement a strategy pattern with spring?

后端 未结 3 2050
孤城傲影
孤城傲影 2021-01-03 12:09

I have a web application developped in Java 1.5 with Spring framework. Application contains \"dashboards\" which are simple pages where a bunch of information are regrouped

相关标签:
3条回答
  • 2021-01-03 12:15

    While it is perfectly "correct" to employ the strategy pattern as you have, but considering the fact that you're using Spring - it would be better to employ the Dependency Injection mechanism provided by the Spring framework - might as well put to use what your framework has to offer as one of its core strengths.

    0 讨论(0)
  • 2021-01-03 12:15

    Your solution will create a new instance of PrintDashboardLog for each call to updateSomeField(). This might take up unnecessary time/memory/GC-effort. Also, from a design perspective it makes sense if there is one DashboardLog for each Dashboard, not a new one for each call.

    I think it may be a good idea to use aspects for which Logging is one of the exemplary usecases. Something like:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                                http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                                http://www.springframework.org/schema/aop
                                http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
        <bean id="loggingAspect" class="com.yourcompany.yourapplication.aspects.DashboardLogAspect" />
    
        <aop:aspectj-autoproxy>
            <aop:include name="loggingAspect" />
        </aop:aspectj-autoproxy>
    
    </beans>    
    
    
    package com.yourcompany.yourapplication.aspects;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    
    @Aspect
    public class DashboardLogAspect {
    
        @Around("execution(* com.yourcompany.yourapplication..*Action+.*(..)) && target(target)")
        public Object logActionCall(ProceedingJoinPoint pjp, Object target) throws Throwable {
    
            long before = System.nanoTime();
    
            Object returnValue = pjp.proceed();
    
            long after = System.nanoTime();
            long durationNs = after - before;
    
            String logMsg = target.getClass() + "." + pjp.getSignature().toShortString() + " (" + durationNs + " ns)";
    
            // TODO: store the log message in your database
            System.out.println(logMsg);
    
            return returnValue;
        }            
    }
    

    This logs all calls to application classes with a name ending in 'Action'. It also adds the time each call took to complete. You might want to tweak the Around advice for a specific method name pattern as well. See the AspectJ programming guide

    0 讨论(0)
  • 2021-01-03 12:38

    If each "dashboard" is has a controller, why not call the logging from the controller.

    
    public interface DashboardLog
    {
        void createLog(...);
    }
    
    public class DashboardUno
    implements DashboardLog
    {
        ...
        public void createLog(...)
        { ... }
    }
    
    @Controller
    @RequestMapping("/blah/schmarr")
    public class BlahController
    {
        ...
        @RequestMapping(value = "/xxx")
        public String someMeaningfulName(...)
        {
            DashboardUno elEsUno;
            ... get the dashboard object ...
            elEsUno.createLog(...);
            ...
        }
    }
    0 讨论(0)
提交回复
热议问题