Realtime API 응답 EventType에 따른 처리 구분

2025. 6. 23. 20:24·개발일지

목표

웹 소켓 핸들러에서 Realtime AI 의 응답의 이벤트 타입에 따라 분기문을 통해 처리 방법을 구분하는 것이 클린 코드가 아니라는 생각이 들었다. 객체 지향의 10대 원칙 중 하나가 else if, else 문을 활용하지 않는 것이다. 각 이벤트 타입에 맞게 처리(handle) 로직을 클린하게 구현하는 방법에 대해 학습한다.

과정

분기문을 통해서 구분짓지 않는다면 이제 다른 방법으로는 switch 문 혹은 인터페이스 와 Map 을 활용한 방법이 있을 것이다

switch 문을 활용하는 방법은 if 문보다 성능과 가독성 측면에서 더 뛰어난 구현 방식이라고 볼 수 있으나 각각의 케이스마다 처리 로직이 커진다면 이 switch 문을 품고 있는 메서드 또한 무거워지므로 클린코드라고 볼 수는 없을 것이다.

인터페이스와 각 케이스에 맞게 구현체를 구성하고 Map 자료구조를 통해서 해당 타입에 맞는 구현체를 가져와 처리한다면 클린코드라 볼 수 있을 것이다.

인터페이스

public interface RealtimeEventHandler {
    RealtimeEventType getSupportedType();
    void handle(String sessionId, AiToServerRealtimeMessage message);
}

인터페이스는 두 개의 메서드로 이루어진다.

getSupportedType() 는 해당 핸들러가 어떤 타입에 대한 핸들러인지를 반환하는 메서드이다.

handle(sessionId, message) 는 이벤트 타입에 맞는 처리를 위한 메서드이다.

구현체

위의 인터페이스를 구현한 예시 구현체이다.

@Component
@RequiredArgsConstructor
public class AudioDeltaEventHandler implements RealtimeEventHandler {
    private final AudioStreamingUseCase audioStreamingUseCase;

    @Override
    public RealtimeEventType getSupportedType(){
        return RealtimeEventType.RESPONSE_AUDIO_DELTA;
    }

    @Override
    public void handle(String sessionId, AiToServerRealtimeMessage message){
        audioStreamingUseCase.forward(sessionId, new ServerToClientAudioMessage(message.delta()));
    }
}

디스패처

@Slf4j
@Component
public class RealtimeEventDispatcher {
    private final Map<RealtimeEventType, RealtimeEventHandler> handlerMap;

    @Autowired
    public RealtimeEventDispatcher(List<RealtimeEventHandler> handlers) {
        this.handlerMap = handlers.stream()
                .collect(Collectors.toUnmodifiableMap(
                        RealtimeEventHandler::getSupportedType,
                        handler -> handler
                ));
    }

    public void dispatch(String sessionId, AiToServerRealtimeMessage message){
        RealtimeEventType type = message.type();
        log.info("Realtime Event type: {}", type);

        if(!handlerMap.containsKey(type)) return;

        RealtimeEventHandler handler = handlerMap.get(type);
        handler.handle(sessionId, message);
    }
}

디스패처는 내부 필드에 Map 저장 공간을 가져 핸들러를 보관한다. 여기서 주목할 부분이 생성자의 파라미터이다. 파라미터의 타입을 List<RealtimeEventHandler> 로 정의한다면 스프링 빈 객체로 등록된 RealtimeEventHandler 구현체들이 자동 주입이 된다. 따라서, 해당 객체를 생성하는 시점에 Map 에 핸들러를 등록할 수 있다.



'개발일지' 카테고리의 다른 글

웹 소켓 핸들러 예외 처리  (0) 2025.06.20
주변 사용자 조회 로직 변경  (0) 2025.03.11
사용자 위치 변경에 대한 기능 수정  (0) 2025.03.11
[소프티어 부트캠프] 지도(공유) 기능에 대한 고찰  (1) 2025.03.11
'개발일지' 카테고리의 다른 글
  • 웹 소켓 핸들러 예외 처리
  • 주변 사용자 조회 로직 변경
  • 사용자 위치 변경에 대한 기능 수정
  • [소프티어 부트캠프] 지도(공유) 기능에 대한 고찰
khw7385
khw7385
khw7385 님의 블로그 입니다.
  • khw7385
    khw7385 님의 블로그
    khw7385
  • 전체
    오늘
    어제
    • 분류 전체보기 (43)
      • 코딩테스트 (7)
      • 자바 (3)
      • 스프링 (3)
      • cs (7)
        • 자료구조 (3)
        • 알고리즘 (1)
        • 객체지향 (3)
      • 개발일지 (6)
        • 트러블슈팅 (1)
      • 데이터베이스 (3)
        • Redis (2)
        • MySQL (1)
      • 기타 (2)
      • devops (6)
      • LG CNS AM INSPIRE (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
khw7385
Realtime API 응답 EventType에 따른 처리 구분
상단으로

티스토리툴바