Layered Architecture 계층 구조
일반적으로 Layered Architecture는 다음과 같은 계층으로 구성됩니다:
- Presentation Layer (프레젠테이션 계층):
- 사용자 인터페이스와 관련
- 사용자가 시스템과 상호작용하는 인터페이스 제공
- 예시: Controller 클래스
@Controller
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/users/{id}")
public String getUser(@PathVariable Long id, Model model) {
UserResponse user = userService.getUserById(id);
model.addAttribute("user", user);
return "userDetail";
}
@PostMapping("/users")
public String createUser(@ModelAttribute UserRequest userRequest) {
userService.createUser(userRequest);
return "redirect:/users";
}
}
- Application Layer (응용 계층):
- 비즈니스 로직을 처리
- 사용자의 요청을 받아 처리
- 데이터를 조작
- 다른 계층과 상호작용
- 예시: Service 클래스
@Service
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
public UserService(UserRepository userRepository, UserMapper userMapper) {
this.userRepository = userRepository;
this.userMapper = userMapper;
}
public UserResponse getUserById(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
return userMapper.toResponse(user);
}
public void createUser(UserRequest userRequest) {
User user = userMapper.toEntity(userRequest);
userRepository.save(user);
}
}
- Domain Layer (도메인 계층):
- 핵심 비즈니스 로직과 규칙을 처리
- 도메인 객체와 이들 간의 관계를 정의
- 비즈니스 규칙과 정책이 포함
- 시스템의 핵심 기능을 담당
- 예시: domain, Entity
public class User {// 시스템의 도메인 엔티티
//속성들
private Long id;
private String name;
private String email;
private String password;
public User(String name, String email, String password) {
this.name = name;
this.email = email;
this.password = password;
}
public void changeEmail(String newEmail) {
// 이메일 변경과 관련된 --> 비즈니스 규칙
if (!newEmail.contains("@")) {
throw new IllegalArgumentException("Invalid email address");
}
this.email = newEmail;
}
// Getter 및 Setter 메서드
}
- Infrastructure Layer (인프라스트럭처 계층):
- 데이터베이스 접근, 외부 시스템 통신, 파일 입출력 등 기술적인 세부 사항을 처리
- 예시: Spring Data JPA 리포지토리
public interface UserRepository extends JpaRepository<User, Long> {
}
고수준 모듈, 저수준 모듈
- 고수준 모듈 (High-Level Module):
- 비즈니스 로직이나 도메인 계층에 가까운 계층
- 시스템의 중요한 비즈니스 규칙과 기능을 포함
- Application Layer, Domain Layer
- 저수준 모듈 (Low-Level Module):
- 기술적인 세부 사항이나 외부 시스템과의 상호작용을 담당하는 계층
- Infrastructure Layer
고수준 모듈 보호의 의미
- 저수준 모듈에 대한 의존성을 최소화하고,
- 저수준 모듈이 고수준 모듈의 구현에 영향을 주지 않도록
- 시스템의 설계가 변경될 때 고수준 모듈이 쉽게 영향을 받지 않도록 함
- 시스템의 유지보수성과 확장성을 높임
예시
- 의존성 역전 원칙 (Dependency Inversion Principle, DIP):
- 저수준 모듈이 고수준 모듈에 의존하지 않도록
- 인터페이스나 추상 클래스에 의존하게 하는 원칙
- 이를 통해 고수준 모듈이 구체적인 구현이 아닌
- 추상화된 인터페이스에 의존하게 되어
- 저수준 모듈이 변경되더라도 고수준 모듈이 쉽게 영향을 받지 않음
- 인터페이스나 추상화를 사용하여 의존성을 제어
// 고수준 모듈 (Application Layer)
public class OrderService {
private final PaymentProcessor paymentProcessor;
public OrderService(PaymentProcessor paymentProcessor) {
this.paymentProcessor = paymentProcessor;
}
public void processOrder(Order order) {
paymentProcessor.process(order);
}
}
/*
OrderService는
구체적인 결제 처리 구현(PaypalPaymentProcessor)이 아닌
PaymentProcessor 인터페이스에 의존하
결제 처리 방법이 변경되더라도
OrderService는 수정할 필요가 없다
*/
// 저수준 모듈 (Infrastructure Layer)
public class PaypalPaymentProcessor implements PaymentProcessor {
public void process(Order order) {
// PayPal을 통한 결제 처리 변경될 예정
}
}
Layered Architecture에 따라 고수준 모듈을 보호하는 구성?
- 시스템의 핵심 비즈니스 로직이 변경에 덜 영향을 받도록 설계하는 것
- 저수준 모듈은 고수준 모듈에 직접 의존하지 않고
- 인터페이스와 같은 추상화를 통해 간접적으로 의존
- 시스템의 유연성과 유지보수성을 높임
'Spring' 카테고리의 다른 글
WebFlux (0) | 2024.08.29 |
---|---|
@SpringBootTest, @ContextConfiguration, Servlet Context, Servlet, Dispacher Servlet (0) | 2024.08.21 |
@EnableFeignClients, @FeignClient 연관성 (0) | 2024.08.12 |
git ignore, commit history 삭제 (2) | 2024.07.31 |
cannot find method 'value' (0) | 2024.07.31 |