Intro::
헥사고날 아키텍처에 대한 정리본입니다.
헥사고날 아키텍쳐란?
헥사고날 아키텍처(Hexagonal Architecture)는 시스템의 내부와 외부를 명확히 분리하여 더 유연하고 테스트 가능하며 유지보수하기 쉬운 구조를 만드는 것을 목표로 하는 아키텍처 패턴입니다. 이 아키텍처는 "포트와 어댑터(Ports and Adapters)" 아키텍처라고도 불리며, 비즈니스 로직을 중심에 두고 다양한 외부 시스템(예: 데이터베이스, 웹 서비스, 사용자 인터페이스 등)과의 연결을 어댑터를 통해 관리합니다.
- 도메인(Domain): 애플리케이션의 비즈니스 로직이 위치하는 곳입니다. 도메인은 외부 시스템에 의존하지 않으며, 도메인 모델과 서비스를 포함합니다.
- 포트(Ports): 도메인과 외부 시스템 간의 인터페이스입니다. 입력 포트와 출력 포트로 나뉘며, 도메인에서 외부 시스템으로 데이터를 전송하거나 데이터를 받는 역할을 합니다.
- 어댑터(Adapters): 포트와 외부 시스템 간의 구체적인 구현입니다. 어댑터는 데이터베이스, 메시지 큐, REST API 등의 외부 시스템과의 통신을 담당합니다.
3계층 구조와의 비교
전통적인 3계층 구조는 프레젠테이션 계층, 비즈니스 계층, 데이터 접근 계층으로 나뉘어져 있습니다.
- 프레젠테이션 계층: 사용자 인터페이스와 관련된 모든 로직을 포함합니다.
- 비즈니스 계층: 애플리케이션의 핵심 비즈니스 로직을 처리합니다.
- 데이터 접근 계층: 데이터베이스와의 상호작용을 관리합니다.
차이점
- 의존성 방향:
- 3계층 구조: 데이터 접근 계층은 비즈니스 계층에 의존하며, 비즈니스 계층은 프레젠테이션 계층에 의존합니다. 상위 계층은 하위 계층을 참조합니다.
- 헥사고날 아키텍처: 도메인 로직이 중심에 있고, 도메인은 외부 시스템에 의존하지 않습니다. 모든 의존성은 도메인 바깥쪽으로 향합니다.
- 테스트 용이성:
- 3계층 구조: 각 계층이 강하게 결합되어 있어, 개별 계층의 테스트가 어려울 수 있습니다.
- 헥사고날 아키텍처: 도메인 로직이 외부 시스템과 분리되어 있어, 도메인의 독립적인 테스트가 용이합니다.
아키텍처 비교 예시 코드
3계층 구조
// UserService.java public class UserService { private UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public void createUser(String name, String email) { User user = new User(name, email); userRepository.save(user); } } // UserRepository.java public interface UserRepository { void save(User user); } // UserRepositoryImpl.java public class UserRepositoryImpl implements UserRepository { public void save(User user) { // 데이터베이스에 사용자 저장 } }
헥사고날 아키텍처
// CreateUserUseCase.java public interface CreateUserUseCase { void createUser(String name, String email); } // CreateUserUseCaseImpl.java public class CreateUserUseCaseImpl implements CreateUserUseCase { private UserRepository userRepository; public CreateUserUseCaseImpl(UserRepository userRepository) { this.userRepository = userRepository; } public void createUser(String name, String email) { User user = new User(name, email); userRepository.save(user); } } // UserRepository.java public interface UserRepository { void save(User user); } // UserRepositoryAdapter.java public class UserRepositoryAdapter implements UserRepository { public void save(User user) { // 데이터베이스에 사용자 저장 } }
- CreateUserUseCase 를 통해 비즈니스 로직을 정의하고 CreateUserUseCaseImpl 에서 구현
- UserRepository 를 구현한 UserRepositoryAdapter 를 사용함으로서 repository 의존성을 낮춤
Loading Comments...