HJW's IT Blog

3 Layered vs Clean Architecture 본문

개발 개념

3 Layered vs Clean Architecture

kiki1875 2025. 1. 31. 17:16

#3Layered #CleanArchitecture

3계층 아키텍처 vs 클린 아키텍처 비교표

비교 항목 3계층 아키텍처 (Three-Tier Architecture) 클린 아키텍처 (Clean Architecture)
구조 ① Presentation (UI) 계층
② Business Logic (Service) 계층
③ Data (Repository) 계층
① Entities (도메인 모델)
② Use Cases (비즈니스 로직)
③ Interface Adapters (Controller, Presenter, Gateway)
④ Frameworks & Drivers (DB, UI, External API)
주요 개념 계층별 역할을 나누어 관심사 분리 의존성 방향을 내부(core)로 향하게 하여 높은 유지보수성과 테스트 용이성 제공
의존성 흐름 UI → Service → Repository (하위 계층이 상위 계층을 의존) 바깥 계층이 안쪽 계층을 의존 (Inner Circle → Outer Circle)
데이터 흐름 클라이언트 요청이 UI를 통해 Service 계층을 거쳐 Repository를 통해 DB에서 데이터를 처리 비즈니스 로직(Use Case)이 중심이 되고, 외부 인터페이스(Adapter)는 이를 지원하는 형태
유연성 & 확장성 비교적 제한적 (계층 간 강한 결합이 발생할 수 있음) 높은 유연성 (구현체 변경이 용이, 테스트가 쉬움)
의존성 방향 하위 계층이 상위 계층을 의존하는 경우가 많음 외부가 내부를 의존하며, 내부(core)는 외부에 의존하지 않음
장점 - 구조가 단순하고 직관적
- 빠른 개발 가능
- 기존 시스템과 연계 용이
- 도메인 로직을 중심으로 설계 가능
- 유지보수성과 테스트 용이
- 의존성 역전을 통해 유연한 설계 가능
단점 - 서비스 계층이 점점 비대해지는 문제 발생 가능
- 변경 시 계층 간 영향이 큼
- 테스트 용이성이 낮음
- 초기 설계 및 학습 비용이 큼
- 프로젝트 규모가 작으면 과도한 설계가 될 수도 있음

🚀 클린 아키텍처의 핵심 : 의존성 역전 (Dependency Inversion)

기존 3계층 방식에선 Service 가 직접 Repository 를 호출하는 형태이다. 그렇다면, 비즈니스 로직 -> 데이터 접근 계층 으로 의존성이 흐르게 된다.

클린 아키텍처와의 차이는 여기서 발생한다. 클린 아키텍저에서는 비즈니스 로직이 데이터 접근 방식에 대해 전혀 모르게 만드는 것이 목표이다.

👉 즉, "비즈니스 로직이 DB를 몰라야 한다" 는 것이 가장 중요한 포인트이다.

클린 아키텍처는 비즈니스 로직(Service)이 Repository 가 아닌 Port(Interface) 에 의존하게 하며, Port 의 실제 구현은 Adapter 계층에서 하게 만듬으로써 이를 달성한다.

👉 UseCase(Service) 는 오직 "데이터가 필요하다" 라는 사실만 알아야 한다.

🚀 3 계층 설계에서도 Repository를 추상화 할수 있지 않나?

 

다음과 같은 3 Layered 설계가 있다.

 

public interface OrderRepository {
    Order save(Order order);
    Optional<Order> findById(Long id);
}

public class JpaOrderRepository implements OrderRepository {
    @Override
    public Order save(Order order) {
        // JPA 사용
    }

    @Override
    public Optional<Order> findById(Long id) {
        // JPA 사용
    }
}

public class MySqlOrderRepository implements OrderRepository {
    @Override
    public Order save(Order order) {
        // MySQL JDBC 사용
    }

    @Override
    public Optional<Order> findById(Long id) {
        // MySQL JDBC 사용
    }
}

 

 

이 코드에서도 OrderRepository interface 만 사용하면 , DB 변경시 구현체만 갈아 끼울 수 있다. 유연성도 확보되며, Service 코드가 특정 기술에 직접 의존하지도 않는다.

 

⚠ 하지만 여전히 부족한 이유

 

여전히 아키텍처의 방향성이 잘못 되어 있다. 비즈니스 로직이 여전히 DB 중심 으로 설계되어 있다.

문제점 1 : OrderRepository 인터페이스는 여전히 Repository 중심적

 

  • 인터페이스를 사용하지만 결국 Repository 중심이다
  • 비즈니스 로직에서 Repository를 제외할 수 없다
  • 만약 DB 없이도 서비스가 동작해야 하는 상황이라면? ex) Test, 도메인 로직 실행 등...

 

문제점 2 : 비즈니서 로직과 DB 사이의 불완전한 분리

 

  • 의존성의 흐름이 Service -> Repository 이다
  • DB가 비즈니스 로직을 모르게 해야 한다는 클린 아키텍처의 원칙에 어긋난다
  • 결국 Service 가 어떤 Repository 구현체를 쓰는지 신경 써야 한다.

 

✅ 클린 아키텍처 : Port & Adapter 적용

 

🔹 Port (Interface) 분리

 

public interface OrderRepositoryPort {
    Order save(Order order);
    Optional<Order> findById(Long id);
}
  • 이때, Port 는 Repository 가 아님을 명시한다. 해당 Port 는 오직 Use Case 만을 위한 인터페이스지, DB를 위한 것이 아니다.

 

🔹 Adapter (구체적 구현체)

 

public class JpaOrderRepositoryAdapter implements OrderRepositoryPort {
    private final JpaOrderRepository jpaRepository;

    public JpaOrderRepositoryAdapter(JpaOrderRepository jpaRepository) {
        this.jpaRepository = jpaRepository;
    }

    @Override
    public Order save(Order order) {
        return jpaRepository.save(order);
    }

    @Override
    public Optional<Order> findById(Long id) {
        return jpaRepository.findById(id);
    }
}
  • OrderRepositoryPort 를 Adapter 가 구현한다
  • 기술 스택 변경시 Adapter 만 수정하면 된다
  • Use Case 는 Adapter 를 전혀 몰라도 된다.

 

🔹 Use Case (비즈니스 로직)

 

public class OrderService {
    private final OrderRepositoryPort orderRepository;

    public OrderService(OrderRepositoryPort orderRepository) {
        this.orderRepository = orderRepository;
    }

    public void processOrder(Order order) {
        // 비즈니스 로직 처리
        orderRepository.save(order);
    }
}
  • Use Case 는 OrderRepositoryPort만 바라보므로, 어떤 DB를 사용하는지 몰라도 된다.
  • DB 와 비즈니스 로직의 완전한 분리

 

🚀 결론: 클린 아키텍처는 "비즈니스 로직을 기술적인 개념과 완전히 분리"하기 위해 필요하다!

 

3 layered 아키텍처 에서도 인터페이스를 활용하면 어느정도의 유연성은 확보할 수 있다. 하지만 여전히 Repository 개념을 포함하는 이상 DB와 저장 방식이 변경될 때 비즈니스 로직도 영향을 받을 가능성이 있다.

 

즉 클린 아키텍처의 핵심은 비즈니스 로직이 저장 방식을 전혀 몰라도 되도록 만드는 것이다.

 

"나는 데이터를 저장해야 한다" (클린 아키텍처)
"나는 Repository를 써야 한다" (3계층 아키텍처)