Post

이주헌님 포트폴리오 4주차 작업 내용 피드백

메가스터디IT아카데미 SpringBoot 백엔드 개발자 과정 주말반 (25.02.22 ~ 25.09.13). 이주헌님의 포트폴리오 4주차 작업 내용에 대한 피드백

이주헌님 포트폴리오 4주차 작업 내용 피드백

이주헌님 포트폴리오 4주차 작업 내용 피드백

작성일: 2025-09-12
github에 push된 코드를 바탕으로 장점, 단점, 그리고 개선사항을 정리했습니다.
아래 사항은 참고만 하시고 적용 여부는 본인이 직접 판단하시면 됩니다.

안녕하세요, 주헌님. 마지막 피드백이 되겠네요. 4주차 작업 내용을 확인했습니다. 특히 이번 주 미션이었던 데이터베이스 연동과 하드코딩 제거에 많은 노력을 기울이신 점이 돋보입니다. 마지막인 만큼 전체적인 관점에서 상세하게 피드백을 작성했습니다.

잘된점 (Good Points)

프로젝트 전반에 걸쳐 SpringBoot의 기본 개념을 잘 이해하고 적용하고 계신 점이 인상적입니다.

1. 체계적인 프로젝트 구조

  • 파일: controllers, services, mappers, models
  • 내용: 기능별로 패키지를 명확하게 분리하여 프로젝트 구조를 체계적으로 구성했습니다. 이는 Spring Framework의 핵심 원칙인 관심사의 분리(Separation of Concerns)를 잘 따르고 있는 좋은 예입니다. 앞으로 프로젝트 규모가 커지더라도 유지보수가 매우 용이할 것입니다.

2. RESTful API와 웹 페이지 컨트롤러의 분리

  • 파일: controllers/, controllers/apis/
  • 내용: 웹 페이지를 반환하는 컨트롤러와 데이터(JSON)를 반환하는 RESTful API 컨트롤러를 apis라는 하위 패키지로 분리하여 관리하는 방식은 매우 훌륭합니다. 역할이 다른 컨트롤러를 명확하게 구분함으로써 코드의 가독성과 관리 효율성을 높였습니다.

3. 생성자 주입(Constructor Injection)을 통한 의존성 관리

  • 파일: EnjoyController.java
  • 코드:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    public class EnjoyController {
        private final FacilityService facilityService;
        private final FacilityClosureService closureService;
    
        public EnjoyController(FacilityService facilityService, FacilityClosureService closureService) {
            this.facilityService = facilityService;
            this.closureService = closureService;
        }
        // ...
    }
    
  • 내용: Spring에서 가장 권장되는 의존성 주입 방식인 ‘생성자 주입’을 사용하고 있습니다. 이를 통해 final 키워드를 사용하여 의존 객체의 불변성을 보장하고, 순환 참조와 같은 잠재적인 문제를 컴파일 시점에 발견할 수 있는 장점이 있습니다.

4. MyBatis의 동적 SQL 활용

  • 파일: FacilityMapper.java
  • 코드:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    @Select("<script>"
            + "SELECT id, type, name, ... "
            + "FROM facilities "
            + "<where>"
            + "  type = 'ATTRACTION' "
            + "  <if test='zone != null and zone != ""'>AND zone = #{zone}</if>"
            + "  <if test='keyword != null and keyword != ""'>"
            + "    AND (name LIKE CONCAT('%',#{keyword},'%') OR summary LIKE CONCAT('%',#{keyword},'%'))"
            + "  </if>"
            + "</where>"
            // ...
            + "</script>")
    public List<Facilities> selectAttractions(@Param("zone") String zone, @Param("keyword") String keyword);
    
  • 내용: MyBatis의 <script>, <where>, <if>와 같은 동적 SQL 태그를 능숙하게 사용하여 다양한 검색 조건에 유연하게 대응하는 쿼리를 작성했습니다. 하드코딩을 제거하고 재사용성 높은 코드를 작성하려는 노력이 돋보입니다.

개선점 (Areas for Improvement)

기능 구현은 훌륭하게 해내셨지만, 코드의 안정성과 유지보수성을 한 단계 더 높이기 위한 몇 가지 제안 사항입니다.

1. 보다 구체적인 예외 처리 (개선 권고)

  • 파일: EnjoyController.java, line 41-45
  • 코드:
    1
    2
    3
    4
    5
    
    try {
        item = facilityService.getById(id);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    
  • 내용: Exception이라는 포괄적인 예외를 잡아 RuntimeException으로 다시 던지고 있습니다. 이렇게 하면 원래 발생했던 예외의 종류가 무엇인지 파악하기 어려워 디버깅을 방해할 수 있습니다.
  • 제안:
    1. Service 계층에서 getById가 데이터를 찾지 못했을 때 DataNotFoundException과 같은 커스텀 예외를 발생시키고,
    2. @ControllerAdvice@ExceptionHandler를 사용하여 이 예외를 전역적으로 처리하면 컨트롤러 코드가 훨씬 깔끔해지고 예외 관리도 중앙에서 할 수 있게 됩니다.

2. SQL 쿼리 가독성 개선 (제안)

  • 파일: ShowMapper.java
  • 코드:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    -- ...
    CASE
      WHEN s.category = 'PHOTO' THEN '포토타임'
      WHEN s.venue LIKE '%퍼레이드 코스%' THEN '퍼레이드'
      -- ...
    END AS tag
    FROM shows s
    -- ...
    GROUP BY
      s.id, s.name, ...,
      (CASE
         WHEN s.category = 'PHOTO' THEN '포토타임'
         -- ...
       END)
    -- ...
    
  • 내용: SELECT 절에서 AS tag로 별칭(alias)을 부여한 CASE 표현식이 GROUP BY 절에서 그대로 반복되고 있습니다. 쿼리가 길어지고 복잡해질수록 가독성과 유지보수성을 떨어뜨리는 원인이 될 수 있습니다.
  • 제안: 대부분의 데이터베이스에서는 GROUP BY 절에서 SELECT 절에서 선언한 별칭을 사용할 수 있습니다. GROUP BY 절을 GROUP BY s.id, s.name, ..., tag 와 같이 수정하면 쿼리가 훨씬 간결하고 명확해집니다.

총평 및 앞으로의 방향

이번 프로젝트를 통해 SpringBoot를 사용하여 웹 애플리케이션의 기본 구조를 설계하고, MyBatis를 이용해 데이터베이스와 연동하는 핵심적인 역량을 훌륭하게 보여주셨습니다. 특히 하드코딩된 데이터를 실제 DB 데이터로 전환하는 과정에서 많은 고민과 노력을 하신 점이 인상 깊습니다.

지금의 탄탄한 기본기 위에 아래와 같은 목표를 가지고 나아가시면 더욱 뛰어난 개발자로 성장하실 수 있을 것입니다.

  1. 테스트 코드 작성: Service 로직이나 Controller의 동작을 검증하는 단위 테스트(Unit Test) 및 통합 테스트(Integration Test) 코드를 작성하는 습관을 들여보세요. 테스트는 코드의 안정성을 비약적으로 높여주고, 리팩토링에 대한 자신감을 심어줍니다.
  2. 보안 및 설정 관리: application.properties에 민감한 정보(DB 비밀번호 등)를 직접 작성하기보다, 환경 변수나 외부 설정 파일을 통해 안전하게 관리하는 방법을 학습해 보세요. 또한, 특정 환경에만 의존하는 설정(파일 경로 등)을 분리하여 어떤 환경에서든 유연하게 동작하는 코드를 작성하는 연습을 해보는 것을 추천합니다.
  3. 고급 기능 도전: 현재까지의 기능을 바탕으로 사용자 인증/인가(Spring Security), 예매 기능 등 조금 더 복잡한 기능을 구현해 보며 문제 해결 능력을 길러보는 것을 추천합니다.

짧은 기간 동안 스스로 학습하며 이만큼의 결과물을 만들어내신 것은 정말 대단한 일입니다. 앞으로도 지금처럼 꾸준히 나아가시길 응원하겠습니다. 고생 많으셨습니다!

This post is licensed under CC BY 4.0 by the author.