[TIL] clean architecture

김영광·2026년 1월 28일

clean architecture, 앱 뿐만 아니라 소프트웨어의 크기가 커질 때 완벽에 가장 가깝게 구현할 수 있는 방법이다.
의존성 주입을 통해 각 모듈별 결합도를 느슨하게 만든다.
오늘은 강의를 통해 알게된 지식을 정리해보고자 한다.

🔎 clean architecture가 뭔데

클린 아키텍처는 SOLID의 원칙에 따라 설계된 소프트웨어 개발 방식이다.
관심사에 따라 구조가 분리되며, 서로에 대한 의존성이 외부에서 내부로 모이는 특성을 가지고 있다.

다음은 클린 아키텍처 틀을 도식화한 그림이다.
의존성을 외부에서 내부로 흐르며 안쪽으로 들어갈수록 순수 언어로 작성된다.
Flutter에서는 Dart언어로 작성된다.

클린 아키텍처를 두고 Layer를 나누는 방식은 제각각이지만, 오늘은 강의 내용을 바탕으로 정리해본다.
먼저, Entities 계층에는 비즈니스의 핵심을 나타내는 객체가 들어간다.
모든 상태가 여기에 포함되는 것은 아니지만, 흔히 관리되는 주요 데이터가 여기에 포함된다.
data layer에 속한다.

Use Cases 계층은 사용자가 시스템을 어떻게 사용할지를 정의한다.
지금까지 riverpod을 통해서 구현해온 특정 기능은 use cases 단으로 넘어가며, vm은 해당 usecase를 받아 사용한다.
domain layer에 속한다.

Interface Adapters는 ui layer와 domain layer를 이어주는 징검다리와 같은 역할을 하고 있다.
굳이 분류하자면 ui layer에 가깝다.

가장 바깥쪽 부분에는 핵심 데이터나 로직과 전혀 관련 없는 것들이 속한다.
외부 데이터 저장소(DB)나 화면에 띄워지는 위젯(UI)가 여기에 속한다.

🔎 사용 이유

가장 큰 이유를 한 단어로 정리하자면 "유지보수"라고 할 수 있다.
계층별로 완벽한 분리가 이루어져 있어 코드의 수정사항이나 추가사항을 쉽게 추가하거나 변경할 수 있다.

예를 들어, DB의 변경이 있거나 UI의 변경사항이 있어도 복잡하게 얽혀있는 부분이 없기에 쉽게 가감할 수 있다.
이는 인터페이스를 통해 가능해지게 되는데 뒤에서 다루겠다.

다음 이유는 테스트 용이성이다.
Mocking, 즉 Dummy Data를 이용한 로직 테스트에 용이하다.

마지막은 스파게티 코드 방지이다.
각각 계층별 역할이 명확하게 나타나기에, 어떤 개발자가 오던 쉽게 파악이 가능하다.

⭐ 즉, 소프트웨어를 부드럽고 유연하게 만들기 위해 사용한다

🔎 DIP, 의존성 역전 원칙

앞에 잠깐 설명했듯이, 클린 아키텍처의 시작은 SOLID 원칙에서 시작됐다.
그 중 피날레라고 생각되는 부분은 DIP, 의존 역전 원칙인데 이는 의존성의 방향을 전환하는 것을 의미한다.

주로 의존성은 고수준 모듈에서 저수준 모듈로 흐른다.
고수준 모듈은 실제 비즈니스 로직을 담당하는 모듈을 의미하며, 저수준 모듈은 반대로 외부 데이터나 API 통신을 담당하는 모듈을 의미한다.

여기서 의존성을 먼저 정리하고 넘어가자.
의존성은 한 모듈이 특정 기능을 실행하려고 할 때, 다른 로직의 서비스를 필요로 하는 경우를 의미한다.
쉽게 생각하면, "나 이거 필요해 내놔(해줘)"하고 있는지를 생각하면 된다.

사실 의존성 역전 원칙이라고 하기에는 모호한 부분이 있다.
의존성이 아예 반대로 꺾이는 것은 아니기 때문이다.
정확하게는 고수준 모듈과 저수준 모듈 사이에 위에서 말했던 interface를 정의해 사용한다.

DIP의 핵심을 정리하자면 다음과 같다.

  • 고수준 모듈과 저수준 모듈은 서로에게 의존해서는 안 되며, 추상화(interface)에만 의존해야 한다.
  • 추상화는 간결해야 하며, 세분화 되어야 한다.
  • 추상화는 세부사항에 의존해서는 안된다.

⭐ DIP의 실질적 이점

그럼 대체 왜 interface를 가운데에 끼고 사용할까?
가장 큰 이유는 SOLID 원칙, 그리고 clean architecture의 주요 이유는 결합도와 관련이 있다.
의존성이 단방향으로 흐르게 되면, 결국에는 최상단 의존성에 의해 애플리케이션이 흔들릴 경우가 반드시 생긴다.

하지만, DIP를 사용하게 되면 결합도를 낮춰 하위 모듈을 변경해도 상위 모듈을 직접적으로 수정하지 않아도 된다.

또, 유연한 확장이 가능하다.
개방폐쇄 원칙에 따라 수정에는 닫히고, 개방에는 열려있는 구조가 완성된다.

profile
주니어 개발자

0개의 댓글