Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

밤빵's 개발일지

[TIL]20240724 쓰리 레이어 아키텍처(Three-Layer Architecture) 본문

개발Article

[TIL]20240724 쓰리 레이어 아키텍처(Three-Layer Architecture)

최밤빵 2024. 7. 24. 21:48

쓰리 레이어 아키텍처(Three-Layer Architecture)

오늘 개발일지에서는 전통적인 소프트웨어 설계 패턴 중 하나인 쓰리 레이어 아키텍처(Three-Layer Architecture)에 대해 공부했다. 이 아키텍처는 응용 프로그램을 세 개의 주요 계층으로 나누어 설계하는 방법으로, 나에게도 조금은 익숙한 설계 패턴이다. 쓰리 레이어 아키텍처의 개념과 장점, 각 계층의 역할, 그리고 예시를 통해 어떻게 적용할 수 있는지에 대해 정리했다!

 

▶ 쓰리 레이어 아키텍처란?

쓰리 레이어 아키텍처(Three-Layer Architecture)는 소프트웨어 애플리케이션을 프레젠테이션(Presentation) 계층, 비즈니스 로직(Business Logic) 계층, 그리고 데이터 액세스(Data Access) 계층의 세 개의 계층으로 나누어 설계하는 구조를 말한다. 이러한 계층 구조는 각 계층이 명확한 역할을 가지도록 해서, 응집도는 높이고 결합도는 낮추는 방식으로 설계된다.

 

→ 프레젠테이션 계층 (Presentation Layer):

사용자 인터페이스와 직접 상호작용하는 계층으로, 데이터를 입력받고 결과를 사용자에게 보여준다. 웹 애플리케이션에서는 주로 컨트롤러와 뷰가 이 계층에 속한다.

→ 비즈니스 로직 계층 (Business Logic Layer):

애플리케이션의 핵심 로직을 담당하는 계층으로, 비즈니스 규칙을 처리하고 데이터의 흐름을 제어한다. 서비스(Service) 계층으로도 불리며, 데이터를 처리하고 유효성을 검사하는 등의 작업을 수행한다.

→ 데이터 액세스 계층 (Data Access Layer):

데이터베이스나 외부 데이터 소스와 상호작용하는 계층으로, CRUD(Create, Read, Update, Delete) 작업을 처리한다. 이 계층은 데이터베이스 접근 코드를 캡슐화하여 다른 계층이 데이터 소스와 직접 상호작용하지 않도록 한다.

 

▶ 쓰리 레이어 아키텍처의 장점

쓰리 레이어 아키텍처를 사용하면 여러 가지 장점을 얻을 수 있다.

 

→ 유지보수성 향상:

각 계층이 독립적으로 관리되므로, 특정 계층의 변경이 다른 계층에 영향을 최소화한다. 이를 통해 코드 수정이 더 용이해진다.

→ 코드 재사용성 증가:

비즈니스 로직과 데이터 접근 로직을 분리함으로써, 같은 로직을 여러 곳에서 재사용할 수 있다. 예를 들어, 동일한 비즈니스 로직이 다른 UI에서 사용될 수 있다.

→ 테스트 용이성:

각 계층이 독립적이기 때문에 단위 테스트가 더 쉬워진다. 비즈니스 로직 계층을 독립적으로 테스트할 수 있고, 프레젠테이션 계층과 데이터 액세스 계층은 별도로 테스트할 수 있다.

→ 유연한 확장성:

계층 구조는 애플리케이션의 확장성을 높여준다. 예를 들어, 프레젠테이션 계층을 웹 애플리케이션에서 모바일 애플리케이션으로 변경하더라도 비즈니스 로직과 데이터 액세스 계층은 그대로 유지할 수 있다.

→ 명확한 책임 분리:

각 계층은 명확한 역할과 책임을 가지므로, 코드의 가독성과 이해도가 높아진다. 이는 협업 과정에서 큰 도움이 된다.

 

▶ 각 계층의 역할과 예시 코드

쓰리 레이어 아키텍처를 Java와 Spring Boot를 사용한 예시이다. 예시는 간단한 도서 관리 애플리케이션으로, 책 정보를 CRUD로 처리하는 기능을 구현했다.

 

▽ 프레젠테이션 계층 (Controller):

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/books")
public class BookController {

    private final BookService bookService;

    @Autowired
    public BookController(BookService bookService) {
        this.bookService = bookService;
    }

    @GetMapping("/{id}")
    public Book getBook(@PathVariable Long id) {
        return bookService.getBookById(id);
    }

    @PostMapping
    public Book createBook(@RequestBody Book book) {
        return bookService.saveBook(book);
    }

    @DeleteMapping("/{id}")
    public void deleteBook(@PathVariable Long id) {
        bookService.deleteBook(id);
    }
}

→ BookController 클래스는 REST API 엔드포인트를 정의하고, BookService를 통해 비즈니스 로직 계층과 상호작용한다.

프레젠테이션 계층은 사용자로부터 입력을 받고, 입력을 비즈니스 로직 계층으로 전달하며, 최종 결과를 사용자에게 반환한다.

비즈니스 로직 계층 (Service):

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Optional;

@Service
public class BookService {

    private final BookRepository bookRepository;

    @Autowired
    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    public Book getBookById(Long id) {
        return bookRepository.findById(id).orElseThrow(() -> new RuntimeException("Book not found"));
    }

    public Book saveBook(Book book) {
        return bookRepository.save(book);
    }

    public void deleteBook(Long id) {
        bookRepository.deleteById(id);
    }
}

→ BookService 클래스는 BookRepository를 사용하여 데이터베이스와 상호작용하며, 프레젠테이션 계층에 비즈니스 로직을 제공한다. 비즈니스 로직 계층은 애플리케이션의 비즈니스 로직을 처리하고, 프레젠테이션 계층과 데이터 액세스 계층 간의 중재자 역할을 한다.

데이터 액세스 계층 (Repository):

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
    // 기본적인 CRUD 메서드가 자동으로 제공된다.
}

→ BookRepository는 JpaRepository를 상속하여 기본적인 CRUD 메서드를 제공하며, 데이터베이스와의 직접적인 상호작용을 캡슐화한다. 데이터 액세스 계층은 데이터베이스와 상호작용하여 데이터를 처리한다. Spring Data JPA를 사용하여 간단한 CRUD 기능을 제공한다.

 

▶쓰리 레이어 아키텍처 사용 시 주의사항

쓰리 레이어 아키텍처는 유연하고 유지보수하기 좋은 구조를 제공하지만, 몇 가지 주의할 점이 있다:

 

→ 복잡도 관리:

계층을 너무 많이 세분화하거나, 지나치게 많은 책임을 부여하면 오히려 복잡도가 증가할 수 있다. 각 계층은 단일 책임 원칙(Single Responsibility Principle, SRP)을 따르도록 설계해야 한다.

→ 중복 코드 방지:

계층 간에 코드가 중복되지 않도록 주의해야 한다. 예를 들어, 데이터 액세스 계층과 비즈니스 로직 계층에서 동일한 검증 로직이 중복되지 않도록 관리해야 한다.

→ 트랜잭션 관리:

비즈니스 로직 계층에서 트랜잭션 관리를 신중하게 해야 한다. 특히 여러 데이터 액세스 계층 메서드를 호출할 때는 트랜잭션 경계를 명확하게 정의해야 한다.

→ 성과 유지:

각 계층이 독립적으로 설계되었더라도, 지나치게 많은 메서드 호출로 인해 성능에 영향을 줄 수 있다. 필요한 경우 계층 간의 호출을 최적화해야 한다.

 

▶ 마무리

쓰리 레이어 아키텍처(Three-Layer Architecture)의 개념과 장점, 각 계층의 역할, 그리고 실제 예시 코드를 통해 이를 어떻게 적용할 수 있는지 알아보았다. 쓰리 레이어 아키텍처는 프레젠테이션, 비즈니스 로직, 데이터 액세스의 세 계층으로 구성되어 있으며, 유지보수성과 코드 재사용성을 높이는 데 효과적이다. 그러나 복잡도를 관리하고, 중복 코드와 트랜잭션 관리를 신중하게 해야 한다. 이 아키텍처를 통해 더 유연하고 유지보수하기 쉬운 애플리케이션을 설계할 수 있다.