Clean Architecture란 무엇인가?(개념)(1)
안녕하세요. 1000JI입니다 :)
최근에 회사 프로젝트들이 어느정도 마무리되면서 그동안 미뤄왔던 개발 블로그를 쓰게 되었습니다.
왜 제 첫 블로그글 주제가 Clean Architecture가 되었느냐? 하면...
iOS 개발을 시작하고나서 줄곧 Clean Architecture에 대한 얘기를 들으면서,
계층 분리에 따른 의존성 방향?, 유지보수성 증가? 좋지좋지! 하면서도
막상 클린 아키텍처 기반으로 개발해봐! 설명해봐! 라고 했을 땐
내가 제대로 이해하고 있는걸까?라는 생각이 들었습니다.
그래서! 클린 아키텍처의 기본부터 어떻게 활용하면 좋을지, 내 생각은 어떤지를 정리해보고자 쓰게 되었습니다.
부족한 부분이나 궁금한 부분이 있다면 언제든지 편하게 댓글 남겨주세요 :)
Clean Architecture(클린 아키텍처)란?
자! 영어로 쓰기 힘드니까 한글로 쓰겠습니다.(이하 클린아키텍처)
도대체 클린 아키텍처 누가 만들었냐? '로버트 C. 마틴'이라는 분이 "클린 아키텍처"라는 제목으로
블로그에 글을 쓰면서 알려지게 되었다고 합니다.
다른 블로그 글 보니까 소프트웨어 개발 방법론 중 "에자일", 또 SOLID(솔리드)원칙도 이분이 만드셨다고...
도대체 얼마나 머리가 좋은...... :)
요즘 주요 아키텍처들을 살펴보면 RIBs(Router Interactor Builder), Clean Swift(VIP) 등
여러 아키텍처가 나오는데 대부분의 아키텍처들은 클린아키텍처의 핵심 원칙을 따르고,
코드의 가독성과 유지보수성, 테스트 가능성을 높이기 위해 설계되었다고 생각합니다.
그렇단 얘기는 클린아키텍처를 공부한다면 "다른 아키텍처들과 비교했을 때에도 설계의 본질을 파악하는데 쉽지 않을까?"란 생각이 들었습니다.
그래서 클린아키텍처가 간략하게 얘기하면 뭔데? 라고 한다면!
클린아키텍처는 SW의 구조를 계층화함으로서 관심사를 분리하고~
그 계층들을 독립적이고 명확한 책임을 가지도록 설계한 구조야~
라고 말 할 수 있을 것 같습니다.
그럼 뒤따라 오는 질문은 "왜 그러면 클린 아키텍처를 사용하려고해?"인데 고것은!
왜 클린 아키텍처를 사용할까?
아마 iOS를 시작하셨던 분들이라면 MVC 아키텍처를 거쳐와보셨을 거라 생각합니다.
그러다 MVVM이 나온 배경은 Controller의 역할이 너무 거대해(Massive)해짐에 따라 ViewModel이 나온 것인데,
사실 MVVM도 하다보면 ViewModel이 점점 Massive 해지는 것을 느낄 수 있습니다.
이에 따라 클린아키텍처를 기반해서 개발한다면 역할 분리를 세밀하게 함으로서
MVVM보다 역할이 더욱 명확해지고 확장성, 유지보수성 뿐만 아니라 테스트 용이성까지 확보 할 수 있게 됩니다.
(하지만 클린아키텍처를 기반해서 개발한다해도 구조를 잘 못 잡으면 Massive 해지는 것은 마찬가지.....)
자! 하지만 이것만 봐서는 "엥? MVVM도 MVC보다 확장성, 유지보수, 테스트 용이성이 보다 향상 되지 않았어?"
라고 생각이 들 수 있기 때문에 구체적인 예를 드는 것이 이해하기가 좀 더 쉬울 것 같습니다.
1. 의존성 역전의 원칙(Dependency Inversion Principle)
- MVVM
- ViewModel이 Model과 View 사이의 중개자 역할을 하여 UI 로직과 비즈니스 로직을 분리합니다.
- 하지만 여전히 일부 의존성이 하위 계층(예: ViewModel이 Model에 의존)을 가질 수 있습니다.
- 클린아키텍처
- 의존성 역전 원칙을 강력히 준수합니다. 즉, 상위 수준의 정책(비즈니스 로직)이 하위 수준의 구현 세부사항에 의존하지 않으며, 반대로 하위 수준의 모듈이 상위 수준의 모듈을 참조합니다.
- 이때! 인터페이스는 추상화(프로토콜)를 통해 이루어지며, 유연성을 크게 증가시킵니다.
이 부분은 추후 예제를 통해 다뤄보겠습니다 :)
2. 레이어드 아키텍처(Layered Architecture)
- MVVM
- 주로 View, ViewModel, Model의 세 가지 주요 레이어가 존재합니다.
- 이는 UI 로직과 비즈니스 로직을 분리하지만, 데이터 소스나 기타 외부 의존성을 명확하게 분리하지는 않습니다.
- 클린아키텍처
- 명확하게 정의된 여러 레이어를 가지고 있으며(하위 다이어그램 및 설명 참조), 각 레이어는 특정한 책임을 집니다.
- 엔티티, 유즈케이스, 인터페이스, UI 등으로 나뉘어지며 이를 통해 각 부분이 독립적으로 개발되고 변경될 수 있습니다.
3. 테스트 용이성
- MVVM
- ViewModel을 쉽게 테스트할 수 있지만, Model이나 데이터 소스가 변경되면 ViewModel 테스트가 어려울 수 있습니다.
- 클린아키텍처
- 각 레이어가 독립적이므로 개별 레이어를 쉽게 테스트 할 수 있으며, 의존성 역전 원칙을 통해 Mock 객체를 사용하여 외부 의존성을 격리하고 테스트 할 수 있습니다.
4. 확장성과 유지보수성
- MVVM
- UI와 비즈니스 로직의 분리로 어느정도 확장성과 유지보수성을 제공합니다.
다만, 시스템이 복잡해지면 ViewModel이 거대해지고, ViewModel와 Model 간의 의존성 문제가 생길 수 있습니다.
- UI와 비즈니스 로직의 분리로 어느정도 확장성과 유지보수성을 제공합니다.
- 클린아키텍처
- 각 레이어와 모듈이 독립적으로 작동하므로, 새로운 기능 추가나 변경 시 특정 레이어만 수정하면 됩니다.
이는 코드의 복잡성을 줄이고, 유지보수를 용이하게 만듭니다.
- 각 레이어와 모듈이 독립적으로 작동하므로, 새로운 기능 추가나 변경 시 특정 레이어만 수정하면 됩니다.
결론
MVVM도 구조를 어떻게 잡냐, 개발을 어떻게 하냐에 따라서 비교 했던 내용들이 해당되지 않을 수 있습니다.
하지만 클린아키텍처를 활용해서 MVVM보다 좀 더 직관적이고 명확하게 그리고 유연한 시스템을 구축할 수 있게 해줍니다.
특히 대규모 시스템이나 복잡한 앱일 수록 더욱 유리하게 작용될거라 생각합니다.
서론이 너무 길었죠? :)
제 자신이나 보는 사람이 더 이해하기 자료를 찾고 작성하느라 글이 점점 길어지는 듯 합니다.
그럼 본격적으로 클린아키텍처에 대해 알아보죠!!
클린아키텍처를 준수 했을 때 만들어지는 구조는?
- Independent of Frameworks: 프레임워크에 독립적이다.
- 핵심 로직이 특정 프레임워크에 의존하지 않도록 설계해야 한다.
그래야 프레임워크가 변경되더라도 핵심 로직을 수정하지 않고도 쉽게 대체 할 수 있다. - ex) 뷰를 표현하는 프레임워크를 변경하더라도 비즈니스 로직은 유지 할 수 있다.
- 핵심 로직이 특정 프레임워크에 의존하지 않도록 설계해야 한다.
- Testable: 비즈니스 로직은 UI, DB, 웹 서버 또는 기타 외부 요소 없이 테스트 할 수 있다.
- 각 구성 요소가 독립적으로 테스트 가능하도록 설계해야 한다.
- 이를 위해 각 요소를 잘게 나누고, 외부 의존성을 최소화하여 단위 테스트가 가능하게 한다.
- ex) 비즈니스 로직을 테스트 할 때 UI 또는 DB와 같은 외부 요소를 필요로 하지 않도록 해야 한다.
- Independent of UI: UI는 시스템을 변경하지 않고도 쉽게 변경 가능하다.
- Independent of Database: 비즈니스 로직이 DB에 의존하지 않는다.
- ex) CoreData -> Realm로 데이터베이스가 변경되어도 비즈니스 로직은 수정 할 필요가 없어야 한다.
- 또는 외부 서버 데이터베이스(Oracle -> MongoDB) 변경해도 바인딩 되지 않으니 상관 없다.
- Independent of any external agency: 비즈니스 로직은 외부에 의존하지 않아야 한다.
- ex) 외부 API를 호출하는 부분을 추상화하여, 해당 API가 변경되더라도 다른 부분에는 영향을 주지 않도록 해야 한다.
라고 합니다..!
공통적으로 말하고 있는 것들이 의존하지 않는다. 라는 문구가 많죠? :)
각 특징들을 읽으면 그치그치.. 맞아맞아... 그게 독립적이고 그게 의존성 분리를 잘한 것이지! 라고 생각이 드는데요.
근데 글을 읽다보니까 쓰읍.. 뭔가 이걸 표현하는 그림이 있으면 좋겠다(?)라고 생각이 들곤 했는데요.
마침 블로그 글을 보니까 관련된 다이어그램이 있더라구요?
오.. 검색시에 많이 나오는 다이어그램이죠?
사실 저는 이 다이어그램을 보고 아 이렇게 되어있구나... 했지만......
구체적으로 어떻게 구분을 지어서 봐야할까, 실제 코드로 어떻게 구현해야할까 라는 생각이 들었답니다.
여기서 중요한 개념은 "와 그러면 원의 가짓수를 늘려서 엄청 세분화 해야겠다!"라는 것보다
아래에서 쓸 "의존성 규칙을 어떻게 가져갈 것인가"입니다.
의존성 규칙(Dependency Rule)
위의 다이어그램을 보면 화살표 모양이 안쪽 원으로 향하는 것을 볼 수 있습니다.
"저게 무슨 방향이지?" 라고 생각이 드시면서 "의존성 방향인가?"라고 생각이 드신다면 맞습니다.
코드의 종속성은 안쪽으로만 향할 수 있습니다.
그렇게 된다면 안쪽의 있는 원은 바깥쪽의 원을 모르기 때문에 바깥쪽 원을 수정한다고 해서,
안쪽의 원에는 영향이 없어야 한다는 것입니다.
정리하면 Outer Circles(바깥쪽 원)은 Inner Circles(안쪽 원)에서 언급해서는 안됩니다.(함수, 클래스 등등)
그러다보니 안쪽으로 향해갈 수록 수정하는 횟수가 적어야하기 때문에 추상화가 많아지거나
DTO 같은 변하지 않는 고수준의 컴포넌트들이 들어가게 되고,
바깥쪽으로 갈 수록 그것들을 활용한 저수준의 컴포넌트, 즉 상세 정보(구현)을 담게 됩니다.
네! 여기까지가 클린아키텍처의 검색 시 나오는 기본적인 내용 또는 개념들(?)입니다.
이제 그러면 어떻게 계층화를 했고 레이어를 어떻게 구분했고 다이어그램에 나오는 것들은 도대체 뭐야?
더 설명이 필요해! 한다면 2번째 올릴 글을 참고해주세요 :)
각 계층 레이어에 대해 살펴보겠습니다 :)
글 내용 중 이해가 안되시거나 부족한 부분! 틀린 부분이 있다면 꼭 댓글 남겨주세요!
부족한 부분이 많습니다 :)
읽어주셔서 감사합니다.

참고 사이트
https://zeddios.tistory.com/1065
Clean Architecture
안녕하세요 :) Zedd입니다. Zedd신곡 나왔는데...엄청 좋아요 갓제드ㅠ 이거들으면서 쓰는 중 오늘은..클린 아키텍쳐 + MVVM에 대해서 공부를 해보려고 합니다! 클린 아키텍쳐는 한번쯤은 들어보셨을
zeddios.tistory.com