Spring Boot 에서 if else 를 어떻게 제거 하 는 지 에 대해 서 말씀 드 리 겠 습 니 다.

7365 단어 SpringBootifelse
머리말
crossoverJie 의 글'정책 모드 를 이용 하여 if else 코드 를 너무 많이 최적화 합 니 다.'을 보고 영감 을 받 았 습 니 다.전략 모델 을 이용 하여 너무 많은 if else 코드 를 간소화 할 수 있 습 니 다.글 에서 스 캔 을 통 해 프로세서 의 자체 등록 을 실현 할 수 있다 고 언급 했 습 니 다.저 는 여기 서 Spring Boot 프레임 워 크 에서 의 실현 방법 을 소개 합 니 다.
수요
이곳 은 업무 수 요 를 가상 하여 모두 가 쉽게 이해 할 수 있 게 한다.만약 에 주문 시스템 이 있다 고 가정 하면 안의 한 기능 은 주문 의 유형 에 따라 서로 다른 처 리 를 하 는 것 이다.
주문 실체:

public class OrderDTO {
  
  private String code;

  private BigDecimal price;

  /**
   *     
   * 1:    ;
   * 2:    ;
   * 3:    ;
   */
  private String type;
  
  // ...    get / set ...
  
}

서비스 인터페이스:

public interface IOrderService {

  /**
   *                 
   *
   * @param dto     
   * @return     ,     
   */
  String handle(OrderDTO dto);

}

전통 적 실현
주문 유형 에 따라 if else 를 한 무더기 작성 합 니 다.

public class OrderServiceImpl implements IOrderService {

  @Override
  public String handle(OrderDTO dto) {
    String type = dto.getType();
    if ("1".equals(type)) {
      return "      ";
    } else if ("2".equals(type)) {
      return "      ";
    } else if ("3".equals(type)) {
      return "      ";
    }
    return null;
  }

}

전략 모드 구현
전략 모델 을 이용 하여 두 줄 만 있 으 면 업무 논 리 를 실현 할 수 있 습 니 다.

@Service
public class OrderServiceV2Impl implements IOrderService {

  @Autowired
  private HandlerContext handlerContext;

  @Override
  public String handle(OrderDTO dto) {
    AbstractHandler handler = handlerContext.getInstance(dto.getType());
    return handler.handle(dto);
  }

}

위의 방법 에 Handler Context 를 주입 한 것 을 볼 수 있 습 니 다.이것 은 프로세서 컨 텍스트 입 니 다.서로 다른 업무 처리 장 치 를 저장 하 는 데 사 용 됩 니 다.구체 적 으로 다음 글 에서 설명 하 겠 습 니 다.우 리 는 그 중에서 추상 적 인 프로세서 Abstract Handler 를 가 져 와 서 그 방법 으로 업무 논 리 를 실현 합 니 다.
이제 우리 의 주요 업무 논 리 는 프로세서 에서 이 루어 졌 기 때문에 몇 개의 주문 유형 이 있 으 면 몇 개의 프로세서 에 대응 하 는 지 알 수 있 습 니 다.이후 수요 변화 로 주문 유형 이 추 가 됐 습 니 다.해당 프로 세 서 를 추가 하면 됩 니 다.상기 OrderServiceV2Impl 은 전혀 변경 할 필요 가 없습니다.
우 리 는 먼저 업무 처리 장치 의 작성 방법 을 봅 시다.

@Component
@HandlerType("1")
public class NormalHandler extends AbstractHandler {

  @Override
  public String handle(OrderDTO dto) {
    return "      ";
  }

}

@Component
@HandlerType("2")
public class GroupHandler extends AbstractHandler {

  @Override
  public String handle(OrderDTO dto) {
    return "      ";
  }

}

@Component
@HandlerType("3")
public class PromotionHandler extends AbstractHandler {

  @Override
  public String handle(OrderDTO dto) {
    return "      ";
  }

}

우선 모든 프로세서 가 spring 용기 에 추가 되 어야 하기 때문에@Component 주 해 를 추가 해 야 합 니 다.그 다음 에 사용자 정의 주 해 를 추가 해 야 합 니 다.@Handler Type 은 이 프로세서 가 어떤 주문 유형 에 대응 하 는 지 표시 하 는 데 사 용 됩 니 다.마지막 으로 AbstractHandler 를 계승 하여 자신의 업무 논 리 를 실현 하 는 것 입 니 다.
사용자 정의 주석@HandlerType:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface HandlerType {

  String value();

}

추상 프로세서 추상 핸들 러:

public abstract class AbstractHandler {
  abstract public String handle(OrderDTO dto);
}
사용자 정의 주석 과 추상 프로세서 가 모두 간단 합 니 다.그러면 어떻게 프로 세 서 를 spring 용기 에 등록 합 니까?
구체 적 인 사고방식 은:
  • 지정 한 가방 을 스 캔 할 때@Handler Type 의 클래스 가 표 시 됩 니 다.
  • 주석 에 있 는 유형 값 을 key 로 하고 해당 하 는 종 류 를 value 로 하여 Map 에 저장 합 니 다.
  • 위의 map 를 구조 함수 매개 변수 로 하여 Handler Context 를 초기 화하 고 spring 용기 에 등록 합 니 다.
  • 우 리 는 핵심 기능 을 Handler Processor 류 에 봉 하여 위의 기능 을 완성 합 니 다.
    HandlerProcessor:
    
    @Component
    @SuppressWarnings("unchecked")
    public class HandlerProcessor implements BeanFactoryPostProcessor {
    
      private static final String HANDLER_PACKAGE = "com.cipher.handler_demo.handler.biz";
    
      /**
       *   @HandlerType,   HandlerContext,     spring  
       *
       * @param beanFactory bean  
       * @see HandlerType
       * @see HandlerContext
       */
      @Override
      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        Map<String, Class> handlerMap = Maps.newHashMapWithExpectedSize(3);
        ClassScaner.scan(HANDLER_PACKAGE, HandlerType.class).forEach(clazz -> {
          //          
          String type = clazz.getAnnotation(HandlerType.class).value();
          //           key,      value,   Map 
          handlerMap.put(type, clazz);
        });
        //    HandlerContext,     spring   
        HandlerContext context = new HandlerContext(handlerMap);
        beanFactory.registerSingleton(HandlerContext.class.getName(), context);
      }
    
    }
    ClassScaner:스 캔 도구 류 소스 코드
    HandlerProcessor 는 BeanFactory PostProcessor 를 실현 해 야 하 며,spring 처리 bean 전에 사용자 정의 bean 을 용기 에 등록 해 야 합 니 다.
    핵심 작업 이 완료 되 었 습 니 다.Handler Context 에서 해당 하 는 프로 세 서 를 어떻게 가 져 오 는 지 확인 하 십시오.
    HandlerContext:
    
    public class HandlerContext {
    
      private Map<String, Class> handlerMap;
    
      public HandlerContext(Map<String, Class> handlerMap) {
        this.handlerMap = handlerMap;
      }
    
      public AbstractHandler getInstance(String type) {
        Class clazz = handlerMap.get(type);
        if (clazz == null) {
          throw new IllegalArgumentException("not found handler for type: " + type);
        }
        return (AbstractHandler) BeanTool.getBean(clazz);
      }
    
    }
    BeanTool:bean 도구 클래스 가 져 오기
    \#getInstance 방법 은 유형 에 따라 대응 하 는 class 를 가 져 오고 class 유형 에 따라 spring 에 등 록 된 bean 을 가 져 옵 니 다.
    마지막 으로 주의 하 세 요.HandlerProcessor 와 BeanTool 은 스 캔 되 거나@Bean 방식 으로 명시 적 으로 등록 해 야 프로젝트 가 시 작 될 때 역할 을 발휘 할 수 있 습 니 다.
    총결산
    정책 모드 를 이용 하여 복잡 한 if else 코드 를 간소화 하고 유지 하기 편리 하 며 사용자 정의 주석 과 자체 등록 방식 을 이용 하여 수요 의 변경 에 편리 하 게 대응 할 수 있 습 니 다.본 고 는 대체적인 사고방식 을 제공 할 뿐 많은 세부 사항 을 유연 하 게 변화 시 킬 수 있다.예 를 들 어 매 거 진 유형,또는 정적 상수 등 을 사용 하여 주문 의 유형 으로서 더 좋 은 방법 을 생각 할 수 있 을 것 이 라 고 믿는다.
    모든 예시 코드 를 보십시오.handler_demo
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기