Как эффективно реализовать шаблон стратегии с весны? - PullRequest
3 голосов
/ 29 декабря 2010

У меня есть веб-приложение, разработанное на Java 1.5 с Spring Framework. Приложение содержит «инструментальные панели», которые представляют собой простые страницы, на которых перегруппируется куча информации и где пользователь может изменить какой-либо статус. Менеджеры хотят, чтобы я добавил систему регистрации в базу данных для трех из этих панелей мониторинга. Каждая панель управления имеет различную информацию, но журнал должен отслеживаться по дате и имени пользователя.

То, что я хотел бы сделать, это реализовать шаблон Стратегии примерно так:

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:

<bean id="dashboardManagers" class="...DashboardManagers" />

Поэтому в этом решении я не использую внедрение зависимостей. «Правильно» (хорошая практика, производительность, ...) делать это таким образом? Есть ли лучший способ, где я мог бы использовать DI?

Примечание: я не писал базовых вещей, таких как конструкторы и методы получения / установки.

Ответы [ 3 ]

2 голосов
/ 29 декабря 2010

Ваше решение будет создавать новый экземпляр PrintDashboardLog для каждого вызова updateSomeField ().Это может занять ненужное время / память / GC-усилия.Кроме того, с точки зрения дизайна имеет смысл, если для каждой панели мониторинга есть один DashboardLog, а не новый для каждого вызова.

Я думаю, что было бы неплохо использовать аспекты, для которых ведение журнала являетсяпримерные варианты использования.Что-то вроде:

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

В нем регистрируются все обращения к классам приложений с именем, оканчивающимся на «Действие».Он также добавляет время, необходимое для завершения каждого вызова.Возможно, вы захотите настроить совет Around для конкретной модели имени метода.См. Руководство по программированию AspectJ

1 голос
/ 29 декабря 2010

Если у каждой «панели мониторинга» есть контроллер, почему бы не вызвать протоколирование с контроллера.


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(...);
        ...
    }
}
1 голос
/ 29 декабря 2010

Хотя это совершенно «правильно» использовать шаблон стратегии, как у вас, но учитывая тот факт, что вы используете Spring - было бы лучше , чтобы использовать Dependency Injection Механизм, предоставляемый средой Spring - может также использовать то, что может предложить ваша среда, в качестве одного из основных преимуществ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...