Home > Today I Learned > 2026_05_04~2026_05_08 > 2026-05-05 일지

2026-05-05 일지
web spring thymeleaf html

다시 해보는 mvc패턴 정리


서론

프로젝트를 시작하고 mvc 패턴과 내가 맡은 댓글 파트에서 구현할 비지니스 패턴에 대해 좀더 공부가 필요함을 느꼈다.

mvc 패턴


애플리케이션 개발을 쉽게 하기위해 데이터, 프레젠테이션, 프로세싱을 분리

  • 모델
    • 핵심 데이터와 비즈니스 로직을 나타낸다
    • 데이터 저장소와 상호작용, 데이터 처리 및 유효성 검사 수행
    • 독립적으로 작동, 뷰와 컨트롤러와 직접 통신 x
  • 뷰
    • 사용자에게 보여지는 애플리케이션의 UI 일부
    • 모델에서 데이터를 받아 사용자에게 표시
  • 컨트롤러
    • 사용자 입력을 처리
    • 애플리케이션 흐름을 관리
    • 뷰에서 전달된 사용자 입력을 분석
      • 적절한 모델 기능을 호출, 데이터 조작 or 업데이트
      • 다시 뷰로 전달하여 표시

비지니스 로직 처리


  • Controller
    사용자의 요청을 Service Layer에 처리 위임, 이에 대한 결과를 View를 통해 반환받음
    • 사용자에게 UI나 클라이언트, Response를 보내는 역할을 하는 모든 클래스를 포함한다.
    • Client로부터 request를 받고 response를 하는 모든 API를 담는다.
  • Service
    비지니스 로직을 정의하는 레이어 담당, 서비스의 비즈니스 로직을 정의
    • 사용자의 요청을 이행하기 위해 도메인 객체들이 협력하여 요청을 수행하도록 조정할 책임
    • Controller와 도메인 사이 추상화 계층을 제공
    • Controller가 요청한 작업을 수행하기 위해 호출할 수 있는 메소드 집합 제공
    • 사용자로부터 전달받은 데이터를 가공하여 처리, JpaRepository를 상속하는 객체를 가져와 어떤 처리를 할 지 비즈니스 로직을 처리한다.
  • Repository
    스프링 4계층 구조에서 Infrastructure Layer 담당, 외부와의 통신 DB, 메세징 시스템 담당
    • 해당 계층으로 부터 얻어온 정보를 ApplicationLayer

4-tier layer achitecture


  1. 사용자 인터페이스 계층
    • 사용자에게 정보를 보여주고 사용작의 명령을 해석해주는 계층
    • Controller와 매핑
  2. 응용 계층
    • 도메인 객체가 문제를 해결하게 사용
    • 해당 계층에는 비지니스 로직 과 다른 시스템의 응용 계층 과 상호 작용을 하는 계층
    • Service와 매핑
  3. 도메인 계층
    • 업무 단위의 개념, 상황에 다른 정보 , 업무의 규칙 등을 책임 지는 계층
    • 비지니스 패턴이외의 조직이나 클라이언트의 요구를 매핑
  4. 인프라스트럭처 계층
    • 상위 계층을 지원하는 일반화 된 기술적 기능을 제공
    • Repository와 매핑

테스트 코드의 필요성과 구현 필요


내 파트인 댓글 파트는 구현하려면 post가 있어야지 구현할 수 있는 것이라서 간단하게나마 테스트 코드를 구현할 필요를 느끼게 되었다. 그리고 내 코드에 대한 성능이 필요해 보여서 구현을 해보도록 했다.

junit을 사용한 메서드 테스트


assertThat 사용

junit의 함수로 C언어의 strcmp를 사용과 유사하게 쓰인다.
원하는 결과가 나오면 true를 반환하고 다른경우 false가 나오게 된다.

다음은 임의로 assertThat의 결과를 false로 한 경우 나오는 실행창 결과이다.

WARNING: A Java agent has been loaded dynamically (C:\Users\Admin\.gradle\caches\modules-2\files-2.1\net.bytebuddy\byte-buddy-agent\1.17.8\f09415827a71be7ed621c7bd02550678f28bc81c\byte-buddy-agent-1.17.8.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release

필요:"수정 후 댓글"
실제   :"수정 전 댓글"
<클릭하여 차이점 확인>

org.opentest4j.AssertionFailedError: 
expected: "수정 후 댓글"
 but was: "수정 전 댓글"
	at io.thelogmaster.blogmaster.service.CommentServiceTest.댓글을_수정한다(CommentServiceTest.java:108)

이렇게 차이에 관해 나오게 된다.

@Autowired

스프링 컨테이너에서 어노테이션으로 빈을 등록하는 방법은 크게 두가지이다.

  1. @bean을 통한 빈 등록(메서드 레벨)
  2. @Component를 통한 빈 등록(클래스 레벨)

    그리고 @Component를 통해 등록된 빈은 다른 곳에서 @AutoWired를 사용해 의존성을 주입하는 것이 가능하다.

  3. 생성자 주입
    클래스의 생성자에 @Autowired를 붙여 해당 클래스 타입의 필드들을 찾아 등록한다. 생성자가 하나인 경우는 @Autowired를 붙이지 않아도 자동 주입의 대상으로 인식한다.
  4. 수정할 때 Setter 주입
    메서드에 @Autowired를 붙여 해당 클래스 타입의 빈을 찾아와 의존성을 주입한다.
  5. 필드 주입
    코드는 간결하게 생성가능
    but 인스턴스를 생성한 후에 의존성을 연결하여 순환참조가 만들어질 우려가 있다.

    이경우 @primary, @Qualifier의 사용으로 우선적으로 주입할 클래스를 명시할 수가 있다.

@ResponseBody의 사용

Controller의 메서드를 불러올때 가져오는 것이 뷰가 아닌 데이터인 경우 데이터는 json 데이터로 반환해야 한다. 
이 경우를 위해 비동기로 데이터를 가져와 화면을 갱신하는데 사용해야 한다.

CommentController의 getCommentstByPost()사용

이 경우 return하는 것이 redirection을 위한 http주소가 아닌 Comment에 관한 데이터이기 때문에 @ResponseBody를 사용해 첨부를 했다.

springboot API document 참조하기

https://docs.spring.io/spring-boot/api/java/index.html

gpt를 통해 테스트코드를 생성하는 중 import가 잘못되어 있는 함수가 있어서 이를 살펴보러 방문하였다.
만약 gpt에서 이상한 함수나 import가 잘못되어 있는 경우 api문서에서 확인을 받는 것도 좋은 것 같다.

참고 : ctrl + shift + r : IntelliJ에서 모두 바꾸기