Kotlin

클린 아키텍처(Clean Architecture)

취업하고싶다! 2023. 6. 2. 17:24

클린 아키텍처는 책 클린 코드를 저술한 로버트 마틴이 제안한 시스템 아키텍처로, 기존의 계층형 아키텍처가 가지던 의존성에서 벗어나도록 하는 설계를 제공한다.

한 줄로 정의하자면, 소프트웨어의 관심사를 계층별로 분리하는 소프트웨어 디자인 철학이다.

 

그렇다면 클린 아키텍처는 왜 쓸까?

다른 블로그에서 쓴 예시를 가져왔다.

[여러분이 A 배달 앱의 개발자이며, 어느 날 A 배달 앱이 B 배달 앱과 통합된다고 가정하겠습니다.

이때 여러분은 다음과 같은 요구를 받게 됩니다.

“A 배달 앱 시스템이 잘 되어 있으니 A 앱의 핵심 기능은 유지하고, UI와 DB 쪽만 바꿔 주세요.”

또는 다음과 같은 요구를 받을 수도 있습니다.

“A 배달 앱이 너무 잘되니 서비스를 웹으로 확장해 봅시다.”

비즈니스의 로직은 비슷한데, 변경해야 하는 부분도 많고, 아예 새로 만들 수도 없는 이러한 상황이라면, 여러분은 어떻게 하실 건가요?

만약 클린 아키텍처를 도입했다면, 단순하게 인터페이스 어댑터 영역 프레임워크와 드라이브 영역만 수정하면 됩니다. 왜냐하면 ‘고객과 업체 사이에서 배달 서비스를 중계한다’는 비즈니스 로직은 변하지 않았기 때문입니다. 이와 같이 클린 아키텍처는 비즈니스 로직은 바꾸지 않으면서, 언제든 DB와 프레임워크에 구애 받지 않고 교체할 수 있는 아키텍처인 셈입니다.

클린 아키텍처는 단순한 추상화에 불과합니다. ] 

위의 그림처럼 Domain Layer, Data Layer, Presentation Layer 총 3가지의 레이어로 나누어 분리시킨다. 

Domain Layer는 어떤 레이어에도 의존하지 않고 언어(Java, Kotlin)의 형태로 되어있다.

Data Layera에는 Domain Layer를 의존하고 Presentation Layer는 Data Layer와 Domain Layer를 의존하며 셋은 의존성 주입으로 연결되어 있다.

 

1. Domain Layer

도메인 레이어는 data model, repository(행동 담음), usecase(행동의 최소단위)를 담고 있다.

  • usecase 
    • 사용자의 행동의 최소 단위를 나타내는 클래스 (비지니스 로직으로 클래스와 함수이름으로 짓는다.)
    • 클래스 양이 많아지는 단점이 있지만 전체적인 코드 파악 및 유지/보수 측면에서 이점이 많다.
    • 유스케이스에서는 domain 레이어에서 정의한 Repository 중 알맞은 것을 주입하여 구현하므로 코드의 흐름을 파악하기 용이하다.
  • repository(interface)
    • domain 레이어에서는 인터페이스 형태로 레포지토리를 나타낸다.
  • entity
    • 프레임워크와 의존성을 가지면 안된다. retrofit 등을 통해 얻은 데이터 객체(spec)를 entity로 매핑을 한다.
  • DataResult
    • 이건 선택사항인데 나는 데이터의 분기처리를 위해 sealData인 DataResult를 만들어 데이터를 받아오거나 전달할때의 분기처리를 처리해준다.(Success,Error,NoData 등)

 

2. Data Layer

  • repository(Impl)
    • Domain레이어에 있는 Repository의 추상화되어 있는 interface 받아와서 설계한다. DataLayer의 진입점과 방출점은 repository를 통해야만 한다.
  • remote
    • retorofit등을 통하여 외부에서 가져올때 사용될 여러가지 클래스(service,url)와 서버를 통해 데이터(spec) 등을 모아 두었다.
  • local
    • Room등을 사용하여 내부디바이스에 저장되는 클래스와 형태를 모아두었다. 예시로는 dao,spec,database(Room)등이 있다.
  • Mapper
    • Data레이어에서 remote나 local에서 데이터를 가져오거나 넘겨줄때 다른형태의 데이터 소스를 변경하는데 사용한다.
    • spec(DataSource) <-> entity 로 바꾼다고 생각하면 편하다.

 

3. Present Layer(UI Layer)

  • UI레이어라고 불리며 사용자의 상호작용을 담당한다.
  • View(xml - Activity / Fragment)에서 사용자의 상호작용을 받아오고 표현한다.
  • ViewModel에서는 Domain레이어의 usecase를 주입받아 사용하게 된다.

이 내용을 바탕으로 프로젝트를 설계할 때 레이어들의 역할과 나누는 방식에 대해 알게 되었음

패키지 형식으로 나눌지 모듈 형식으로 나눌지 선택해야 함

둘을 선택할 때는 대부분 규모의 차이로 나뉜다고 한다. 규모가 작으면 패키지 형식을 선택하는 것이 좋다고 한다.

모듈 형식으로 나누게 되면 위에서 말했던 Data Layer - Domain Layer - Presentation Layer의 서로의 의존관계의 강제성을 부여하게 된다.

 

다른 사람이 정리한 그림을 살펴보자.

패키지 구성으로 레이어를 나눔(di, wiget은 무시)

 

모듈 구성으로 레이어를 나눔

위의 사진을 보면 domain layer와 data layer를 모듈로 꺼내 나누었다. 이렇게 했을 때 장점은 의존성에 강제성을 줄 수 있다고 한다.

 

ui layer에서 implementation 하는 모습

위의 사진은 data layer와 domain layer를 의존하는 모습을 설명한다.

 

 

그렇다면 클린 아키텍처를 사용했을 때 가장 큰 장점은 무엇일까?

바로 테스트가 용이하다는 것이 큰 장점이다.

테스트 코드를 짜면서 가장 많이 듣는 얘기로 '테스트 더블'이라는 개념이 있다.

(테스트 더블: xUnit Test Patterns』의 저자인 제라드 메스자로스(Gerard Meszaros)가 만든 용어로 테스트를 진행하기 어려운 경우 이를 대신해 테스트를 진행할 수 있도록 만들어주는 객체를 말한다)

쉽게 말하면 테스트하려는 객체와 연관된 객체가 모호할 때, 대신 만드는 객체라고 할 수 있다.

이를 사용하려면 인터페이스로 정의하고 구현체를 더미로 바꾸는 과정이 필요하다.

 

'Kotlin' 카테고리의 다른 글

Kotlin 면접준비(1)  (0) 2023.06.04
Kotlin- 문법1  (0) 2023.06.02
코틀린 컨벤션  (0) 2023.06.01
UMC project 1주차(23/01/02~23/01/10)  (0) 2023.01.11
UMC 1주차  (0) 2022.12.30