Software Engineering

[Hexagonal Architecture] 1. 헥사고날 아키텍처란?

noahkim_ 2025. 8. 20. 02:08

1. 헥사고날 아키텍처란?

  • 애플리케이션의 핵심 비즈니스 로직을 중심으로 두고 외부 기술 요소를 분리하는 설계 방식
  • ✅ port & adapter를 통해 외부 기술 요소와 느슨하게 결합됨
  • ➡️ 비즈니스 로직이 특정 기술을 직접 의존하지 않도록 하는 것이 목적

 

요청 흐름

  1. 외부 요청
  2. inbound adapter → inbound port → application core → outbound port → outbound adapter
  3. 외부시스템

 

예시) 회원가입 요청

더보기
  1. UserController (Inbound Adapter)
  2. SignUpUseCase (Inbound Port)
  3. SignUpService (Application Core)
  4. UserRepository (Outbound Port)
  5. JpaUserRepositoryAdapter (Outbound Adapter)
  6. Database (외부시스템)

 

vs 레이어드 아키텍처

  • Controller → Service → Repository → Database
  • ✅ 단순해서 이해하기 쉬움
  • ⚠️ 시간이 지나면 Service가 Repository/JPA/DB 구조에 점점 의존하게 됨

 

예시) 단점 - UserService

더보기
@Service
@RequiredArgsConstructor
@Transactional
public class UserService {

    private final UserRepository userRepository;
    private final PostRepository postRepository;
    private final ChatRoomMembershipRepository membershipRepository;
    private final NotificationSettingRepository notificationSettingRepository;
    private final OAuthAccountRepository oauthAccountRepository;
    private final EntityManager entityManager;
    private final ApplicationEventPublisher eventPublisher;

    public void withdraw(Long userId) {
        UserEntity user = userRepository.findById(userId)
            .orElseThrow(UserNotFoundException::new);

        user.withdraw();

        postRepository.hideAllByUserId(userId);
        membershipRepository.deleteAllByUserId(userId);
        notificationSettingRepository.deleteAllByUserId(userId);
        oauthAccountRepository.deleteAllByUserId(userId);

        entityManager.flush();

        eventPublisher.publishEvent(new UserWithdrawnEvent(userId));
    }
}
  • 원래 서비스는 비즈니스 규칙을 표현해야 함
  • 점점 기술적인 것도 신경쓰게 됨
  • ex) DB 구조, JPA Flush 타이밍, 이벤트 발행 타이밍 등

 

2. 핵심 원칙

  • 핵심 비즈니스 로직을 외부 기술로부터 분리하기
  • ➡️ 외부 기술이 내부 비즈니스 로직을 오염시키면 안됨

 

장점

  • 확장성: 핵심 로직을 유지하면서 새로운 기능/기술을 추가할 수 있음
  • 테스트 용이성: 핵심 로직이 외부 의존성이 없으므로 비즈니스 로직을 단위 테스트하기 쉬움
  • 유지 보수성: 역할이 명확히 분리되어 있어 가독성이 좋고 코드 수정 시 영향 범위가 작음

 

예시) 확장성

더보기
알림 생성 로직
   ↓
AlertRepositoryPort
   ↓
MongoAlertRepositoryAdapter
   ↓
MongoDB
알림 생성 로직
   ↓
AlertRepositoryPort
   ↓
PostgresAlertRepositoryAdapter
   ↓
PostgreSQL
  • 기술 변경 시, Adapter만 갈이끼우면 됨

 

예시) 테스트 용이성

더보기
public class PriceAlertService {

    private final MongoTemplate mongoTemplate;
    private final KafkaTemplate<String, Object> kafkaTemplate;

    public void createAlert(Alert alert) {
        // 가격 변동률 판단
        // MongoDB 저장
        // Kafka 발행
    }
}
  • 테스트하려는 것: 가격 변동률 판단 로직
  • 필요해지는 것: MongoDB, Kafka, Spring Context, 설정 파일
  • ⚠️ 외부 시스템 설정 필요

 

public class PriceAlertService {

    private final AlertRepositoryPort alertRepository;
    private final AlertEventPublisherPort eventPublisher;

    public void createAlert(Alert alert) {
        // 가격 변동률 판단
        alertRepository.save(alert);
        eventPublisher.publish(alert);
    }
}

 

예시) 유지 보수성

더보기
  • 비즈니스 규칙 문제 → domain / application
  • HTTP 요청 문제 → adapter-in
  • DB 저장 문제 → adapter-out persistence
  • Kafka 발행 문제 → adapter-out messaging
  • 외부 API 문제 → adapter-out client

 

단점

  • 인터페이스와 클래스가 많아질 수 있음
  • ➡️ 변경 가능성이 큰 외부 기술과, 오래 유지되어야 하는 비즈니스 로직을 분리할 필요가 있을 떄 사용해야 함

 

출처

'Software Engineering' 카테고리의 다른 글

[Hexagonal Architecture] 3. 설계 방식  (0) 2026.07.03
[Hexagonal Architecture] 2. 구성  (0) 2026.06.29