빙수왕의 개발일지

The Clean Architecture, 클린 아키텍쳐 blog 정리 본문

개발/그 외

The Clean Architecture, 클린 아키텍쳐 blog 정리

빙수킹 2021. 10. 31. 19:34

출처

https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

 

Clean Coder Blog

The Clean Architecture 13 August 2012 Over the last several years we’ve seen a whole range of ideas regarding the architecture of systems. These include: Though these architectures all vary somewhat in their details, they are very similar. They all have

blog.cleancoder.com

 

지난 몇 년 동안 우리는 시스템 아키텍처에 관한 다양한 아이디어를 보아 왔다. 다음과 같은... 

 

디테일들은 다양하지만 결국 모두 비슷하다. 뭐가?

이것들은 모두 같은 "separation of concerns 관심사? 관계의 분리" 라는 목표를 가지고 있다.

그리고 목표를 위해 모두 소프트웨어를 계층(layer)으로 나눈다.

적어도 1개의 비즈니스 룰을 위한 layer 있, 적어도 1개의 interface 위한 layer 있다.

 

그리고 아키텍쳐들은 아래를 만족하는 system 만든다.

 

1 Independent of Frameworks.

프레임워크와 무관하다. 라이브러리에 의존하지 않고, 프레임워크를 도구로(as tools) 사용한다.

 

2 Testable.

 business rules UI, 데이터베이스, 웹 서버 또는 기타 외부 요소 없이 테스트할 수 있다.

 

3 Independent of UI.

UI 다른 시스템(ex. 비즈니스 rule ) 변화 없이 변경될 있다.

 

4 Independent of Database.

iOS 치면 realm 사용하건, coredata 사용하건.. DB의 종류에 상관이 없다. (엄연히 말하면 framework지만 암튼)

 

5 Independent of any external agency.

business rule 외부 세계(outside world) 대해 알지 못한다.

-> 여기서 외부세계는 자신 밖의 모두를 말하는 .. 외부 프레임워크나 라이브러리같은것..?

 

 

그리고 이 모든 아키텍쳐들을 실행가능한 단일 아이디어(a single actionable idea)로 통합하려고 한다!!!

그것이 바로 Clean Architecture 의 목적!

 

 

Clean Architecture에서 가장 핵심은, The Dependency Rule이다.

 

The Dependency Rule (종속성 규칙)

각 동심원은 소프트웨어의 다른 영역을 나타낸다. 일반적으로 안쪽으로 갈수록 소프트웨어의 수준이 높아진다. 바깥쪽 원은 메커니즘mechanisms이다. 내부 원은 정책policies이다.

This rule says that source code dependencies can only point inwards. 

규칙에 의하면 소스코드 종속성은 안쪽만 가리킬 수 있다. 내부 circle의 어떤 것도 외부 circle의 무언가에 대해 전혀 알 수 없다. 특히, 바깥쪽 원에 선언된 것의 이름은 안쪽 원의 코드에서 언급되어서는 안 됩니다. 여기에는 함수, 클래스가 포함됩니다. 변수 또는 기타 명명된 소프트웨어 entity.

암튼 결론은 안쪽에서는 밖을 몰라야 하고, 밖에서만 안을 가리킬 수 있다. 예를들어보자면.. 비즈니스 로직(Use Case)에서는 DB가 뭐로 되어있는지 몰라야 한다.

 

이제 나머지 설명들은.. 이 Dependency Rule에 따른 각 계층들의 형태?? 그런것이다.

 

Entities

가장 변경에 영향을 받지 않는 계층.

Entity는 전사적 비즈니스 규칙(Enterprise wide business rules)을 캡슐화 한다. Entity는 메서드가 있는 개체이거나 데이터 구조 및 함수 집합일 수 있다.

그들은 가장 일반적이고 높은 수준의 규칙을 캡슐화한다. 외부에서 무언가가 변경될 때 변경될 가능성이 가장 적습니다. 예를 들어, 이러한 개체가 페이지 탐색 또는 보안 변경의 영향을 받을 것으로 예상하지 않습니다. 특정 애플리케이션에 대한 운영상의 변경은 엔터티 계층에 영향을 미치지 않아야 합니다.

 

Use Cases

이 계층의 소프트웨어에는 응용 프로그램별 비즈니스 규칙이 포함되어 있다

시스템의 모든 usecase를 캡슐화하고 구현한다. 

이 layer의 변경사항이 entity 영향을 미치지 않는다. DB UI, 다른 framework의 변경에 영향을 받지 않는다.

 

Interface Adapters

 

usecase entity 가장 편리한 형식에서 db 또는 web 같은 일부 외부 기관에 가장 편리한 형식으로 데이터를 변환하는 어댑터 세트

예를 들어 계층은 GUI MVC 아키텍처를 완전히 포함한다. (MVVM??)

Presenters Views Controllers 여기다. 여기를 기점으로 안의 어떤 코드도 DB 대해 전혀 없다.

 

Frameworks and Drivers.

 

가장 바깥쪽 계층이다.  Database, the Web Framework, etc. 

많은 코드를 작성하지 않는다.

 

Only Four Circles?

 

ㄴㄴㄴ. 4 이상의 원이 필요할 있다. 하지만 "종속성 규칙" 항상 적용된다. 소스코드 종속성은 항상 안쪽을 가리킨다.

바깥쪽은 detail, 안쪽으로 수록 추상화 수준이 증가한다.

The inner most circle is the most general.

 

Crossing boundaries.

 

코드를 구현하다 보면, usecase에서 presenter을 호출한다던가. 그런 형태가 필요하다.

그러면 Dependency Inversion Rule을 사용하여 모순을 해결한다. 

(*SOLID 중 D인 의존관계 역전 원칙이다. 구체적인 것 보다는 추상화에 의존해야 한다.)

자바에서는 인터페이스, Swift에서는 protocol을 사용하여 해결할 수 있다.

예를 들자면.. usecase에서 presenter을 직접 호출하는 것이 아닌, presenter의 추상화된 protocol를 호출하는 것이다.

 

What data crosses the boundaries.

 

DB에서 쿼리의 결과로 나오는 data format은 "RowStructure"이다.

우리는 경계를 넘어(안쪽으로) RowStructure을 넘기지 않는다. 바깥세계의 형태를 안쪽으로 넘겨서 "종속성 규칙"을 어기고싶지 않기 때문에..

그래서 경계를 넘어 갈때는 항상 inner circle 맞는 형식으로 바꿔주어야 한다.

 

Conclusion

 

이렇게 하면 이점

-> testable 시스템을 만든다.

-> DB 프레임워크같은 바깥쪽 파트에 변경이 생겼을 , 최소 비용?(fuss)으로 요소를 교체할 있다.