복붙노트

[SPRING] 스프링을 사용하여 전략 패턴을 효율적으로 구현하는 방법은 무엇입니까?

SPRING

스프링을 사용하여 전략 패턴을 효율적으로 구현하는 방법은 무엇입니까?

스프링 프레임 워크로 자바 1.5에서 개발 한 웹 애플리케이션이 있습니다. 응용 프로그램에는 일련의 정보가 재 그룹화되고 사용자가 일부 상태를 수정할 수있는 간단한 페이지 인 "대시 보드"가 포함되어 있습니다. 관리자는 3 개의 대시 보드에 대해 데이터베이스에 로깅 시스템을 추가하기를 원합니다. 각 대시 보드에는 정보가 다르지만 로그는 날짜와 사용자의 로그인으로 추적해야합니다.

내가 뭘하고 싶은건 전략 패턴 종류를 구현하는 것입니다.

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를 사용할 수있는 더 좋은 방법이 있습니까?

참고 : 생성자 및 getter / setter와 같은 기본 요소는 작성하지 않았습니다.

해결법

  1. ==============================

    1.당신이 가지고있는 것처럼 전략 패턴을 사용하는 것은 완벽하게 "정확하다". 그러나 Spring을 사용한다는 사실을 고려하면 Spring 프레임 워크가 제공하는 Dependency Injection 메커니즘을 사용하는 것이 더 낫다. 귀하의 프레임 워크는 핵심 강점 중 하나로서 제공되어야합니다.

    당신이 가지고있는 것처럼 전략 패턴을 사용하는 것은 완벽하게 "정확하다". 그러나 Spring을 사용한다는 사실을 고려하면 Spring 프레임 워크가 제공하는 Dependency Injection 메커니즘을 사용하는 것이 더 낫다. 귀하의 프레임 워크는 핵심 강점 중 하나로서 제공되어야합니다.

  2. ==============================

    2.솔루션은 updateSomeField () 호출마다 PrintDashboardLog의 새 인스턴스를 만듭니다. 이것은 불필요한 시간 / 메모리 / GC 노력을 소비 할 수 있습니다. 또한 설계 관점에서 각 대시 보드마다 하나의 DashboardLog가 있으며 각 호출마다 새로운 대시 보드 로그가없는 것이 좋습니다.

    솔루션은 updateSomeField () 호출마다 PrintDashboardLog의 새 인스턴스를 만듭니다. 이것은 불필요한 시간 / 메모리 / 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;
        }            
    }
    

    이렇게하면 모든 호출이 'Action'으로 끝나는 응용 프로그램 클래스에 기록됩니다. 또한 각 통화가 완료되는 데 걸린 시간이 추가됩니다. 특정 메서드 이름 패턴에 대한 Around 조언을 조정할 수도 있습니다. AspectJ 프로그래밍 가이드를 참조하십시오.

  3. ==============================

    3.각 "대시 보드"에 컨트롤러가있는 경우 컨트롤러에서 로깅을 호출하는 것이 좋습니다.

    각 "대시 보드"에 컨트롤러가있는 경우 컨트롤러에서 로깅을 호출하는 것이 좋습니다.

    
    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(...);
            ...
        }
    }
  4. from https://stackoverflow.com/questions/4553377/how-to-efficiently-implement-a-strategy-pattern-with-spring by cc-by-sa and MIT license