CS/CS

레이어드 아키텍처 응용 (Layered Architecture)

annovation 2024. 12. 3. 08:49

아키텍처의 구조

Entity, Repository, Service, Controller로 구성된 레이어드 아키텍처 또는 도메인 중심 설계(DDD)

User Management System
├── Controller (입력 처리)
│     - UserController: 사용자 요청을 처리
├── Service (비즈니스 로직)
│     - UserService: 사용자 생성 및 조회 로직
├── Repository (데이터베이스와 상호작용)
│     - UserRepository: 사용자 데이터를 저장/조회
└── Entity (도메인 모델)
      - User: 사용자 데이터를 표현하는 객체

아키텍처 다이어그램 

[ Client ] → [ UserController ] → [ UserService ] → [ UserRepository ] → [ Database ]

 

  1. 클라이언트(Client)
    • 사용자 요청을 보냄 (예: 브라우저, Postman)
  2. 컨트롤러(UserController)
    • HTTP 요청을 받고 서비스 계층으로 전달
  3. 서비스(UserService)
    • 비즈니스 로직 수행 (유효성 검사, 데이터 변환 등)
  4. 레포지토리(UserRepository)
    • 데이터베이스와 상호작용하여 데이터를 저장/조회
  5. 데이터베이스(Database)
    • 데이터를 실제로 저장하거나 가져옵니다.

예제 : 사용자 관리 시스템

* 구조

 

아키텍처의 데이터 흐름은 다음과 같습니다:

  1. Controller : 사용자 요청을 받아 Service 계층 호출
  2. Service : 비즈니스 로직을 처리하고 Repository와 상호작용
  3. Repository : 데이터베이스와 상호작용하여 데이터를 저장하거나 조회
  4. Entity : 도메인의 핵심 데이터를 표현

 

* 예제 코드 (Spring 기반)

 

1. Entity (User.java)

Entity는 데이터베이스 테이블과 매핑되는 도메인 모델입니다.

import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class User {
    @Id
    private Long id;
    private String name;
    private String email;

    // 기본 생성자
    public User() {}

    // 생성자
    public User(Long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    // Getter와 Setter
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

 

 

2. Repository (UserRepository.java)

Repository는 데이터베이스와의 상호작용을 캡슐화합니다.

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

public interface UserRepository extends JpaRepository<User, Long> {
    // 기본 CRUD 메서드 제공 (save, findById, delete 등)
}

 

 

3. Service (UserService.java)

Service는 비즈니스 로직을 처리하고 Repository와 상호작용합니다.

Service에는 파일과 관련된 내용이 있으면 안됩니다. Service의 로직을 볼 때, 데이터를 메모리에 저장하는지 파일에 저장하는지 DB에 저장하는지 몰라야 합니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    // 사용자 생성
    public User createUser(Long id, String name, String email) {
        if (userRepository.findById(id).isPresent()) {
            throw new IllegalArgumentException("User with ID " + id + " already exists.");
        }
        User user = new User(id, name, email);
        return userRepository.save(user);
    }

    // 사용자 조회
    public User getUserById(Long id) {
        return userRepository.findById(id).orElseThrow(() -> 
            new RuntimeException("User with ID " + id + " not found."));
    }
}

 

 

4. Controller (UserController.java)

Controller는 HTTP 요청을 처리하고 Service를 호출합니다.

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

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    // 사용자 생성 엔드포인트
    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user.getId(), user.getName(), user.getEmail());
    }

    // 사용자 조회 엔드포인트
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}

 

* 데이터 흐름

  1. 사용자 요청
    • 클라이언트가 POST /users 요청을 보냅니다.
    • 요청 본문: { "id": 1, "name": "Alice", "email": "alice@example.com" }.
  2. 컨트롤러(UserController)
    • createUser 메서드가 요청 데이터를 받아 UserService의 createUser 메서드를 호출합니다.
  3. 서비스(UserService)
    • 사용자 ID 중복 여부를 확인하고, 중복이 없으면 새 User 객체를 생성하여 UserRepository에 저장합니다.
  4. 레포지토리(UserRepository)
    • save 메서드가 호출되어 데이터를 데이터베이스에 저장합니다.
  5. 결과 반환
    • 저장된 사용자 객체가 컨트롤러를 통해 클라이언트에 반환됩니다.

확장 가능성

  1. Validation Layer 추가
    • 입력 데이터 유효성 검사를 서비스와 분리
  2. DTO(Data Transfer Object)
    • 엔티티와 요청/응답 데이터를 분리하여 클라이언트와 서버 간 데이터 교환 효율성 향상
  3. Event Handling 추가
    • 사용자 생성 시 이벤트를 발행하여 다른 시스템과 연동

출처

OpenAI ChatGPT (https://openai.com)