如何有效地实施弹簧战略模式?

我有一个使用Spring框架在Java 1.5中开发的Web应用程序。 应用程序包含“仪表板”,这些页面是简单的页面,其中一组信息被重新分组,用户可以在其中修改某些状态。 管理人员希望我在数据库中为三个仪表板添加日志记录系统。 每个仪表板都有不同的信息,但日志应该按日期和用户的登录进行跟踪。

我想做的是实现类似这样的策略模式:

interface DashboardLog { void createLog(String login, Date now); } // Implementation for one dashboard class PrintDashboardLog implements DashboardLog { Integer docId; String status; void createLog(String login, Date now){ // Some code } } class DashboardsManager { DashboardLog logger; String login; Date now; void createLog(){ logger.log(login,now); } } class UpdateDocAction{ DashboardsManager dbManager; void updateSomeField(){ // Some action // Now it's time to log dbManagers.setLogger = new PrintDashboardLog(docId, status); dbManagers.createLog(); } } 

Appcontext.xml:

  

因此,在这个解决方案中,我没有使用dependency injection。 以这种方式做到这一点是“正确的”(良好做法,表现……) 有没有更好的方法可以使用DI?

注意:我没有编写构造函数和getter / setter等基本内容。

虽然使用策略模式完全“正确”,但考虑到你使用Spring这一事实 – 最好采用Spring框架提供的dependency injection机制 – 不妨使用什么您的框架必须提供其核心优势之一。

您的解决方案将为每次调用updateSomeField()创建一个新的PrintDashboardLog实例。 这可能会占用不必要的时间/内存/ GC工作量。 此外,从设计角度来看,如果每个仪表板都有一个DashboardLog,而不是每个呼叫都有一个新仪表板,则这是有意义的。

我认为使用Logging作为示例性用例之一的方面可能是个好主意。 就像是:

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

这会记录对名称以“Action”结尾的应用程序类的所有调用。 它还会增加每次通话完成所需的时间。 您可能还想调整特定方法名称模式的Around建议。 请参阅AspectJ编程指南

如果每个“仪表板”都有一个控制器,为什么不从控制器调用日志记录。

 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(...); ... } }