아키텍처의 구조
Entity, Repository, Service, Controller로 구성된 레이어드 아키텍처 또는 도메인 중심 설계(DDD)
User Management System
├── Controller (입력 처리)
│ - UserController: 사용자 요청을 처리
├── Service (비즈니스 로직)
│ - UserService: 사용자 생성 및 조회 로직
├── Repository (데이터베이스와 상호작용)
│ - UserRepository: 사용자 데이터를 저장/조회
└── Entity (도메인 모델)
- User: 사용자 데이터를 표현하는 객체
아키텍처 다이어그램
[ Client ] → [ UserController ] → [ UserService ] → [ UserRepository ] → [ Database ]
- 클라이언트(Client)
- 사용자 요청을 보냄 (예: 브라우저, Postman)
- 컨트롤러(UserController)
- HTTP 요청을 받고 서비스 계층으로 전달
- 서비스(UserService)
- 비즈니스 로직 수행 (유효성 검사, 데이터 변환 등)
- 레포지토리(UserRepository)
- 데이터베이스와 상호작용하여 데이터를 저장/조회
- 데이터베이스(Database)
- 데이터를 실제로 저장하거나 가져옵니다.
예제 : 사용자 관리 시스템
* 구조
아키텍처의 데이터 흐름은 다음과 같습니다:
- Controller : 사용자 요청을 받아 Service 계층 호출
- Service : 비즈니스 로직을 처리하고 Repository와 상호작용
- Repository : 데이터베이스와 상호작용하여 데이터를 저장하거나 조회
- 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);
}
}
* 데이터 흐름
- 사용자 요청
- 클라이언트가 POST /users 요청을 보냅니다.
- 요청 본문: { "id": 1, "name": "Alice", "email": "alice@example.com" }.
- 컨트롤러(UserController)
- createUser 메서드가 요청 데이터를 받아 UserService의 createUser 메서드를 호출합니다.
- 서비스(UserService)
- 사용자 ID 중복 여부를 확인하고, 중복이 없으면 새 User 객체를 생성하여 UserRepository에 저장합니다.
- 레포지토리(UserRepository)
- save 메서드가 호출되어 데이터를 데이터베이스에 저장합니다.
- 결과 반환
- 저장된 사용자 객체가 컨트롤러를 통해 클라이언트에 반환됩니다.
확장 가능성
- Validation Layer 추가
- 입력 데이터 유효성 검사를 서비스와 분리
- DTO(Data Transfer Object)
- 엔티티와 요청/응답 데이터를 분리하여 클라이언트와 서버 간 데이터 교환 효율성 향상
- Event Handling 추가
- 사용자 생성 시 이벤트를 발행하여 다른 시스템과 연동
출처
OpenAI의 ChatGPT (https://openai.com)
'CS > CS' 카테고리의 다른 글
버퍼 (Buffer) (0) | 2025.01.04 |
---|---|
메서드 체이닝(Method Chaining) (0) | 2024.12.05 |
명령형(imperative) VS 선언형(declarative) 프로그래밍 (1) | 2024.12.05 |
TDD (Test-Driven Development) feat. JUNIT (0) | 2024.12.02 |
Software Architecture (소프트웨어 아키텍처) (0) | 2024.11.26 |