
레이어드 아키텍처레이어드 아키텍처
。각계층이독립적인 특정기능을 집중해서 수행하도록 관리하는 방식
▶SRP준수
。각계층은고수준 상위계층으로부터저수준 하위계층으로단방향 의존성을 가지며상호작용을 수행
▶저수준 계층에서고수준 계층으로의존성을 가지면 안된다.
▶추상화를 통해상위계층은하위계층의 세부사항을 알지 못해도 기능을 활용가능
Spring MVC원리
。보라색:개발자가 작성하는logic
。파란색:스프링이 처리하는logic
▶개발자는Controller,Service,Repository역할의Class를 집중해서 개발
Controller / Service / Repository Layer
。Spring Web의Spring MVC 디자인패턴에서Dispatcher Servlet에서HandlerAdapter를 통해 전달된클라이언트의 실질적인요청을 처리하는3계층
。한책임을 구현 시Controller , Service , Repository로 분할하여 구현
▶ 각각의 기능을 수정하더라도 다른Layer에는 영향이 없어야하며 유지보수성 증진
▶관례상프로젝트내에서 각각의Controller , Service , Repository , DTO종류에 따라패키지도 구별해서 분류해야함.
。레이어드 아키텍처에 따라 각각요청 처리,Business Logic,DB 상호작용에 대한 기능을 독립적으로 구현하며단방향 의존성을 준수해야한다.
▶클라이언트의요청을레이어드 아키텍처를 통한Controller -> Service -> Repository순서로단방향 의존
。실제지라를 통해어플리케이션을개발시에도저수준 클래스 -> 고수준 클래스순서로 개발
▶repository -> service -> repository순서로 개발
▶고수준 모듈을 개발 후저수준 모듈을 개발 시 이를 의존하는고수준 모듈도 함께 고려해야하므로유지보수가 좋지않다.
Controller Layer
。Dispatcher Servlet에서 전달받은요청을 처리 및 응답하는@RequestMapping,@GetMapping, ... 이 선언된method
▶@Controller 클래스내 포함
。Controller는 기능분리를 통해요청과응답, 그리고 어떤Service를 사용할 건지에 대해서만 담당하여 집중
。레이어드 아키텍처상Presentation Layer에 대응
▶ 다음저수준 클래스인Service Class를 의존
▶클래스내Service 클래스 객체를필드로 선언 및의존성주입후요청을 전달
Service Layer:
。Controller에게 전달된요청을 처리하는Business logic을 작성하는클래스
。주로검증로직등을 작성
。각Service Class는인터페이스를 상속하여Controller에서 사용하는Service를 변경하더라도Service 클래스내에서 코드수정이 발생하지않도록 함
▶OCP준수
。MVC내Business Logic작성 및 어떤Repository를 선택하여 데이터를 상호작용할지 정의
。레이어드 아키텍처상Business Layer에 대응
▶ 다음저수준 클래스인Repository Class를 의존
▶클래스내Repository 클래스 객체를필드로 선언 및의존성주입후요청을 전달
。@Service를 선언하여Spring Bean으로 등록
@Service Class는 각Service Logic을추상화한Interface를 우선적으로 정의한 후구현하는 방식을 권고
。Member 기능구현 시 각Service Logic을 추상화한MemberService 인터페이스와 해당인터페이스를 구현한MemberServiceImpl 클래스를 각각 생성
。 단Interface당구현 클래스가 하나밖에없는 경우관습적 추상화가 되나 이건 본인의 취향에 따라 결정.
▶관습적 추상화:관례를 지키고자 불필요한추상화를 수행하는 것
인터페이스public interface MemberService { void createMember(MemberCreateRequest memberCreateRequest); }
구현 @Service 클래스@RequiredArgsConstructor @Service public class MemberServiceImpl implements MemberService { private final MemberRepository memberRepository; @Override @Transactional public void createMember(MemberCreateRequest request){ // } }
Repository Layer
。DB와의상호작용을 담당하는Repository Class
▶DAO(Data Access Obejct) 역할을 수행하는클래스
。레이어드 아키텍처상Persistence Layer에 대응
▶실제 DB를 의존하여 연결됨
▶ 단Jdbc나JPA사용 시 해당구현체( ex.JdbcTemplate, ...)를필드로 선언하여의존성주입하여DB와 상호작용하여 사용
。@Repository를 선언하여Spring Bean으로 등록
。JPA의 경우 해당Repository를JpaRepository 인터페이스를 확장한인터페이스로 대체
실습
패키지별로 구분
Controller@Controller @ResponseBody public class CourseController { private CourseService courseService; // 요청, 응답 역할을 수행하는 Controller // 가장 고수준으로서 Service를 의존 @RequestMapping("/add-course") public void addCourse(){ // Service에 정의된 Business Logic 수행 courseService.insertCourses(); } }
Service// Business Logic 을 수행하는 Service 클래스 // 저수준인 Repository 클래스 의존 @Service @RequiredArgsConstructor public class CourseService { private CourseRepository courseRepository; public void insertCourses(){ // Repository를 통해 DB에 접근 courseRepository.insert(1,"수학"); courseRepository.insert(2,"영어"); } }
Repository// DB와 상호작용하는 Repository 클래스 // 가장 저수준이므로 의존하는 계층이 없다 @Repository public class CourseRepository { JdbcTemplate jdbcTemplate; // JdbcTemplate 구현체 의존성주입 private String insert_sql = """ insert into course_table values(?,?); """; public CourseRepository(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } // JDBC를 통해 DB랑 상호작용 public void insert(int courseId, String courseName){ jdbcTemplate.update(insert_sql, courseId, courseName); } }