클린 아키텍처 애매한 부분 정해 드립니다. (세미나 내용 정리)

jay·2023년 1월 5일
24

세미나 내용 정리

목록 보기
1/3
post-thumbnail

👍 이 글은 NHN Dooray 협업서비스개발그린팀 김민중님의 강연 [NHN FORWARD 22] 클린 아키텍처 애매한 부분 정해 드립니다. 을 보고 정리한 내용입니다.
좋은 강연해주신 연사분께 감사드립니다. NHN 입사하면 커피 사겠습니다.

📣 소제목을 누르면 해당 발표 시간의 영상으로 이동합니다. 내용을 보다가 이해가지 않는 부분이 있다면 편하게 찾아보세요.

⚠️영상에서는 발표자께서 편의를 위해 로버트 마틴(클린 아키텍처의 저자)을 엉클 밥이라고 지칭하셨지만, 여기에서는 로버트 마틴이라고 표기하였습니다. ppt 제목의 경우에는 원본 그대로 놔두었습니다.

들어가기 전에

강연 대상

  • 처음 클린 아키텍처를 공부해보려고 하시는 분
  • 공부를 해보려다가 헷갈리는 부분이 많아서 중도에 포기하신 분
  • 막상 조금씩 적용을 해보고 있는데 이게 맞나 싶은 초급자

다룰 내용

  1. 소프트웨어 아키텍처의 중요성
  2. 좋은 아키텍처를 구성하는 방법
  3. 클린 아키텍처?
  4. 클린 아키텍처는 애매합니다
  5. 결론
  • 처음 클린 아키텍처라는 개념을 제시한 '로버트 마틴'의 '클린 아키텍처'와
    '톰 홈버그'의 '만들면서 배우는 클린 아키텍처'에 많이 기반한 발표

1. 소프트웨어 아키텍처의 중요성

1.1 소프트웨어 아키텍처가 뭐죠?

  • '클린 아키텍처가 중요한가?' 이전에 '소프트웨어 아키텍처가 중요한가?'가 선행되어야하고, 그 이전에 '아키텍처'가 무엇인지 알아야함

1.1.1 소프트웨어 아키텍처가 뭐죠?

  • 아키텍처는 소프트웨어가 제공하는 가치, 기능과 구조 중에 구조에 해당.
  • 보통 기능에 대해서는 동의할텐데, 과연 소프트웨어가 제공하는 가치에 구조가 있는지 의문을 가질 수 있음.

1.1.2 보통 우리는 기능에 집중합니다.

  • 보통 우리는 개발을 한다고 하면 기능에 집중함. 어떤 기능을 제공할건지 정하고, 그 기능이 잘 돌아가게 하는데 집중.
  • 하지만 로버트 마틴은 기능보다 구조가 더 중요하다고 주장.
  • 구조를 잘 만들면 개발하기 좀 수월하긴 하지만, 이게 제공하는 가치에 해당하는게 맞느냐는 의문이 생김.

1.1.3 우리가 흔히 접하는 코드

  • 기능은 방에 들어있는 물건들, 가구들. 구조는 어떤 식으로 배치가 되어 있는지로 비유.
  • 방에 기능(물건)은 많지만, 배치(구조)는 엉망진창. 이 상황에서 새로운 기능인 가습기를 추가한다하면, 원래 있던 물건을 정리해야만 함

1.1.4 우리가 이상적으로 생각하는 코드

  • 기능과 구조들이 정말 잘 배치 되어 있음
    • 기능이 얼마 없는 상황에서는 이렇게 할 수도 있음
    • 그러나 기능이 추가됨에 따라 이렇게 유지하는 것은 불가능.
  • 이런 상황을 목표로 하면 안 됌.

1.1.5 우리가 추구해야 하는 코드

  • 물건들이나 가구들이 빼곡하게 있지만, 나름의 질서가 있음. 맨 처음(1.1.3)의 배치와는 다름
    • 가습기(새 기능)를 놓기 어렵지 않음.
    • 우리가 추구해야 할 코드는 뭔가 많이 들어있지만, 나름의 질서가 있어서 그 구조를 파악하기 어렵지 않은 상태.
  • 즉 원하는 물건(기능)이 있기만 하면 전부가 아니라, 기능을 계속 더하고 뺄 때 구조가 굉장히 중요하다

1.1.6 기능과 구조, 나란히 서도 괜찮나요?

1.1.7 소프트웨어 아키텍처는 구조

  • 즉, 소프트웨어 아키텍처는 기능과 구조 중, 구조에 대한 이야기다

1.2 좋은 아키텍처가 왜 중요한가요?

  • 방에 비유해서 설명을 했는데, 좋은 아키텍처가 그렇게까지 중요한가에 대한 의문은 여전할 수 있음

1.2.1 우리가 회사에서 하는 것

  • 우리가 회사에서 주로 하는 것은 코딩

1.2.2 우리가 회사에서 하는 것 - 프로젝트 시작

  • 코딩을 처음 시작할 때 기능을 제공하기 위해 신규 프로젝트를 생성하고 코드를 작성.
  • 이 때는 기능에 집중하고 구조는 조금 밀어놓을 수 있음.

1.2.3 우리가 회사에서 하는 것 - 유지보수

  • 그런데 실제로 회사에서 많이 하는 것은 유지보수.
  • 유지보수란 컴퓨터에게 원하는 일(기능)을 더 정확히(버그 수정), 더 빠르게(성능 개선), 더 많이(기능 추가) 시키기 위해 코드를 읽고, 이해하고, 코드 수정/추가 하는 것.
    • 우리는 처음 깨끗한 상태에서 시작하는 것 보다는, 이 행위들(유지보수)를 더 많이 함.
    • 코드를 읽고 이해하고 수정하는 데 구조는 굉장히 큰 영향을 끼침.
    • 구조가 잘 짜여있어야지 유지보수하기 수월.
    • 즉, 기능 못지않게 구조가 중요하다.

1.2.4 기능은 구조에 의지한다.

  • 구조가 기능을 뒷받침하고, 기능은 구조에 의지해서 더 안정적이고 더 수월하게 변경이 가능

1.2.5 소프트웨어 아키텍처의 목표 by 엉클 밥

"소프트웨어 아키텍처의 목표는 필요한 시스템을 만들고 유지보수하는 데 투입되는 인력을 최소화하는 것"
-로버트 마틴-

1.2.6 좋은 아키텍처의 중요성 by 엉클 밥

가정) 구조가 좋다 == 수정하기 쉽다 == 수정하는 데 비용(인건비 등)이 적게 든다.

  • 기능 잘 동작 + 구조 엉망 : 지금은 좋지만, 수정하는데 비용이 너무 많이 든다. -> 곧 버려질 프로그램
  • 기능 부족 + 구조 좋음 : 지금은 부족하지만, 수정하는 데 비용이 적게든다. 기능은 추가하면 됨.
  • 논외) 기능 완성 후 변경사항이 없을 프로그램은 개발자가 투입될 이유가 없으므로 논외.

2 좋은 아키텍처를 구성하는 방법

좋은 아키텍처가 굉장히 중요하다는데 동의를 했다면, 잘 구성하는 방법에 대한 의문이 들 것.

2.1 좋은 구조? 좋은 아키텍처? 어떻게 만드나요?

2.1.1 좋은 아키텍처 만드는 방법

  • 클린 아키텍처 책에서 우리가 많이 본 클린 아키텍처 다이어그램에 대해 이야기한 내용은 적다
    • 책에서는 코드를 쉽게 파악하고, 변경할 수 있게 도와주는 규칙들을 나열함.
    • 절반 이상이 각 규칙들이 왜 코드를 쉽게 변경하는데 좋은 구조에 도움이 되는지를 이야기함.
    • 패러다임, 설계 원칙(SOLID), 컴포넌트 응집성 원칙, 컴포넌트 결합 원칙 등등
    • 이런 것들을 잘 지켜서 코딩하면 좋은 아키텍처를 가진 소프트웨어를 만들 수 있음.

2.1.2 더 쉽게 가는 방법은 없나요?

아키텍처 패턴

  • 위 원칙들을 쉽게 적용하기 위한 것이 아키텍처 패턴
    • 발표자께서는 아키텍처 패턴이란 '좋은 아키텍처를 잡기 위한 레시피'라고 정의함.
  • 따라하는 것 만으로 앞의 원칙들의 지켜지고, 그 원칙들에 대해 고민하기 쉬움.
    • 복잡한 구조, 엉망인 구조에서는 그런 원칙들을 지키려해도 너무 많이 들어 엎어야함.
  • 이 패턴이 모든 걸 가져다주는 건 아니지만, 원칙들을 지키기 쉽게 해주는 뼈대라고 보면 됌.
  • 그런 뼈대에는 우리가 흔히 쓰는 계층형 아키텍처가 있고, 클린 아키텍처, 헥사고날 아키텍처라는 것이 있음.

래시피(패턴) 사용법

  1. 일단은 레시피를 따라해 보기
    -> 요리를 처음부터 내 맘대로 변형해서 하려면 엉망이 될 수 있음
  2. 원칙들을 학습하고 이해한 후에 다시 레시피 대로 따라해 보기
  3. 각자의 프로젝트에 레시피를 적용해 보기
  4. 고민이 되는 지점들은 원칙에 맞게, 혹은 크게 벗어나지 않는 선에서 타협하며 적용해 보기

2.2 어떤 아키텍처 패턴을 써야하나요?

후보 1. 계층형 아키텍처

  • 특징
    • 전통적인 수평적 계층화
  • 장점
    • 구조 단순
    • 처음 시작할 때 적합
    • 보편적이어서 모두가 익숙
  • 단점
    • 업무 도메인에 대해 아무 것도 말해 주지 않음
    • 소프트웨어가 커지고 복잡해지면 조직화에 도움 안 됨
    • 데이터베이스 주도 설계 유도
      • 의존성이 웹-> 도메인 -> 영속성으로 흐르므로, 영속성부터 설계를 하게 됌.

후보 2. 클린 아키텍처

  • 특징
    • 도메인이 중심(의존성 역전을 이용)
      • 다형성을 이용해서, 의존성을 거꾸로 올라가게 함
  • 장점
    • 규칙 단순
      • 계층적으로 나눈다
      • 의존성은 핵심 가치인 도메인을 향한다
    • 도메인이 세부 사항에 의존하지 않는다.
      • 계층형에서는 도메인이 영속성이라는 세부사항에 의존
      • DDD 적용 용이(도메인 주도 설계)
      • 비즈니스 규칙에 집중 쉽다.
  • 단점
    • 패키지 구조가 계층형보다 복잡하다.
    • 익숙하지 않아서 처음에 버벅일 수 있다.
    • 레퍼런스가 적다.

3. 클린 아키텍처?

3.1 클린 아키텍처가 뭐죠?

3.1.1 클린 아키텍처란?

  • 로버트 마틴이 오랫동안 개발하면서 본 좋은 아키텍처들의 공통점을 통합하여 만든 것이 클린 아키텍처
  • 차용한 아키텍처들에는 헥사고날 아키텍처, 바운더리 컨트롤 엔티티, 데이터,콘텍스트 앤 인터렉션이 있음.
    • 공통의 목표: 관심사의 분리
    • 공통의 핵심 규칙: 관심사를 분리해 놓은 상태에서 의존성의 방향은 안쪽으로, 고 수준을 향함.
      • 계층형 아기텍처와는 다른 핵심적인 부분

3.1.2 클린 아키텍처 다이어그램

  • 핵심 1. 중요도에 따라 계층을 나눔
    • 계층을 나누는 것은 계층형 아키텍처와 동일
  • 핵심 2. 의존성의 방향은 항상 안쪽, 고수준을 향함
    • 다형성을 이용하여 의존성은 어디서든 역전 가능

3.2 클린 아키텍처 어떻게 학습하나요?

좋은 건 알겠는데 어떻게 학습해야하냐

3.2.1 바이블과 쿡북

클린 아키텍처

  • 저자: 로버트 C. 마틴
  • 유형: 바이블
  • 특징: 수 많은 원칙
  • 내용:
    • 클린 아키텍처에 대해 설명하는 것이 아니라 아키텍처가 왜 중요하고, 좋은 아키텍처 만드려면 지켜야 하는 원칙들을 설명
    • 원칙들에 대해 하나하나 설명하므로 처음 시작하기엔 어려울 순 있음.
    • '쿡북'으로 접해볼 것을 권함

만들면서 배우는 클린 아키텍처

  • 저자: 톰 홈버그 (스프링 컨퍼런스에서도 매번 발표)
  • 유형: 쿡북
  • 특징: 실제로는 한 개파인 헥사고날 아키텍처를 다룸
  • 내용:
    • 굉장히 얇음
    • 이론적인 설명보다는 쭉 따라하면서 배울 수 있음

3.2.2 [책] 클린 아키텍처

  • 클린 아키텍처의 바이블, 좋은 아키텍처의 규범서
    • 수 많은 원칙과 실천법
    • 다이어그램 하나로 이루어져 있지 않음 (아래 다이어그램에 대해 설명하는 전체 406페이지 중에 16페이지 밖에 없음)

3.2.3 [책] 만들면서 배우는 클린 아키텍처

  • 클린 아키텍처를 위한 실천서
    • 실제로는 헥사고날 아키텍처를 다룸
    • 애매하지 않고 단정적인 말투 -> 따라가기 쉬움
    • 처음에 쭉 따라하며 기본 개념 익히기 좋음

3.3 헥사고날 아키텍처?

3.3.1 어떤 구조로 시작하는 게 좋을까요?

  • 잘 모르겠을 땐 헥사고날 아키텍처
    • 클린 아키텍처 기본 다이어그램과 가장 비슷
    • 클린 아키텍처의 확장이라고 보면 됌
      • 클린 아키텍처가 헥사고날과 다른 아키텍처의 공통점을 뽑아 놓은 것이므로
    • 따라할 수 있는 쿡북이나 레퍼런스가 가장 많음 (번역된 쿡북 3권)
      • 테스트 주도 개발로 배우는 객체지향 설계와 실천
      • 만들면서 배우는 클린 아키텍처
      • 만들면서 배우는 헥사고날 아키텍처 설계와 구현

3.3.2 헥사고날 아키텍처

3.3.3 클린 아키텍처 vs 헥사고날 아키텍처

  • 엔티티가 중심에 있고, 유즈 케이스엔티티를 감싸고 있음
    • Input PortOutput Port유즈 케이스에 들어간다고 보면 됌
  • 초록색 컨트롤러, 게이트웨이, 프레젠터스가 바깥쪽 어뎁터에 해당
  • 즉 헥사고날 아키텍처는 클린 아키텍처라고 생각하고 적용해도 무방

3.4 아키텍처별 패키지/클래스 구조 비교

3.4.1 계층형 아키텍처

  • 특징
    • 전통적인 수평적 계층화
  • 장점
    • 구조 단순
    • 처음 시작할 때 적합
    • 보편적이라서 모두가 익숙함
  • 단점
    • 업무 도메인에 대해 아무것도 말해 주지 않음
    • 소프트웨어가 커지고 복잡해지면 조직화에 도움 안됨

3.4.2 기능 기반 패키지

  • 특징
    • 서로 연관된 기능, 도메인 개념에 따라 수직의 얇은 조각으로 나눔
    • 수평적 계층화의 문제를 깨닫고 수직적 계층화로 넘어 오는 경우 많음
      • 수평적 계층화는 패키지 안에 여러가지 도메인이 섞여있게 됌
  • 장점
    • 코드의 상위 수준 구조가 업무 도메인에 대해 무언가를 알려줌
    • 유스케이스가 변경될 경우 변경해야 할 코드를 모두 찾는 작업이 더 쉬워짐
  • 단점
    • 계층 구조가 분리되지 않음

3.4.3 포트와 어댑터(헥사고날)

  • 특징
    • 수직, 수평으로 나눔
    • DB 계층에 대한 의존성 역전
  • 장점
    • 도메인이 다른 세부 사항에 의존하지 않음
      • 모든 것들의 의존성이 도메인을 향함 (클린 아키텍처의 핵심)
    • 수직, 수평형 계층 구조의 장점을 모두 가짐
  • 단점
    • 클래스와 패키지 구조가 더 많아짐

4. 클린 아키텍처는 애매합니다.

  • 쿡북 같은 것을 따라해보다 보면 애매한 부분이 많음
  • 클린 아키텍처는 애매 그 잡채

4.1 클린 아키텍처는 왜 애매한가요?

4.1.1 클린 아키텍처는 왜 애매한가요?

  • 규칙이 너무 단순
    • 핵심 규칙 2가지 외에는 case by case라 애매한 지점이 많을 수 밖에 없다
    • '핵심 2가지 외에는 너의 프로젝트에 맞게 적용을 해라'라고 하니까

4.1.2 애매할 때? 기준이 필요하다

1. 필요한 시스템을 만들고 유지보수하는 데 투입되는 인력 최소화에 유리한가?
2. 소스 코드 의존성이 안쪽으로, 고수준의 정책을 향하고 있는가? 
3. 세부 사항이 변경되어도 도메인(핵심 규칙)에 변경이 없을 것인가?
4. 테스트하기 쉬운가?
5. 각각의 아키텍처 원칙들을 잘 지키고 있는가?

2번을 어기면 클린 아키텍처가 아님. 그냥 그 프로젝트에 맞는 아키텍처를 선택한 것.

4.2 시작할 때 애매한 것들

4.2.1 클린 아키텍처를 적용하면 항상 좋은가요?

이럴 땐 쓰지 마세요

  • 소규모의 프로젝트를 진행할 때
    • 굳이 할 필요없으나 학습 목적이면 해도 됌
  • 프로젝트 개발자 모두가 클린 아키텍처를 이해하고 있지 않을 때 혹은 모두가 사용하기로 합의하지 않았을 때
    • 클린 아키텍처는 프로젝트 전체 구조에 관여하는 것이기 때문에 혼자 맘대로 할 수 있는 것이 아님

4.2.2 코드가 얼마나 늘어나나요?

라인 수나 파일 수보다 패키지 수가 많이 늘어남

4.2.3 패키지를 꼭 이렇게 많이 만들어야 하나요?

  • 방을 정리하려면 가구를 들여놔야 함
  • 깔끔한 상태를 유지하려면 정리정돈을 해야 함.

=> 경계를 뚜렷하게 긋기 위해서는 패키지와 클래스가 더 필요

4.2.4 내가 작업하는 부분에만 적용해 봐도 되나요?

팀 구성원 전부 합의하고 진행해야 합니다

  • 코드 일부가 아니라 패키지 구조가 바뀜
  • 바뀐 패키지 구조를 다른 개발자가 이해하지 못할 수 있음
  • (경험담)

4.3 꼭 다 지켜야 하나요?

4.3.1 지름길, 건너뛰기 괜찮을까?

알아서, 적당히, 잘, 조심스럽게

  • 원칙도 100% 다 지킬수 없음. 원칙끼리 서로 간섭하고 충돌 나는 경우도 있기 때문.
  • 하지만 처음부터 지름길로 가면 나중에 정석대로 못 함.
  • 일단 학습 할 때는 정석대로 해서 체득하고 실전에서 지름길 사용
    • 지름길 사용 시 반드시 클래스 상단 같은 곳에 주석으로 표시해 놔야함

4.3.2 JPA Entity와 Domain Entity, 분리해야 하나요?

  • 화살표 시작하는 부분의 JPA Entity는 원래 데이터 베이스 계층의 어댑터
    • 도메인 Entity랑 JPA Entity랑 굉장히 유사해서 그냥 써도 되는게 아닌가 하고 JPA Entity를 도메인 계층으로 가져와 쓸 수도 있음

=> 하지만 분리했을때 얻는 이득이 큼

  • 하나로 쓰면
    • 클래스, 패키지 구조는 단순화
    • 영속성 계층과 도메인 계층 강결합
    • Domain Entity를 다룰 때 업무 규칙 뿐만 아니라
      • 연관 관계 매핑,
      • 즉시 로딩/지연 로딩 등을 고려해야 함
    • 분리하지 않으면 사실상 클린 아키텍처는 아닌…
  • 분리하면
    • 핵심 업무 규칙에 대한 고민에 집중
  • 경험담
    • 핵심 업무 규칙에 수정이 있을 때, DB 스키마 변경이나 데이터 마이그레이션을 먼저 고민

4.3.3 JPA Repository는 어디에 해당하나요?

  • 헥사고날 아키텍처에서는 의존성 역전을 위해 범용적인 인터페이스를 만들고, 어뎁터로 구현을 해서 jpa를 써라라고 말함
    • 왜나면 출력 포트는 유즈 케이스가 필요로 하는 형태대로 유지가 되어야함
    • 유즈 케이스가 db 세부사항에 의존하면 도메인이 영향을 받기 때문.

4.3.4 유스 케이스가 다른 유스케이스를 호출해야 할 때?

컴포넌트를 별도 코드 베이스로 분리하려는 게 아니라면 직접 호출

  • 직접 호출해도 의존성 규칙에 위배되지 않음
    • 하지만 의존성이 순환되지 않게 주의해야 함.

4.3.5 유스 케이스를 꼭 인터페이스 뽑아야 하나?

인터페이스로 뽑아야 함

  • Controller가 Service의 구현에 대해 너무 많이 알지 못하도록 막기 위해 존재.
    • 방향이 바뀌는 것은 아니지만, 도메인을 보호하는 것 만큼이나 컨트롤러도 도메인에 대해 보호를 받아야 함.
  • 사고의 경계를 그어주는 역할
  • 인터페이스는 api 스펙 같은 것.
    • 우리가 뭔가를 논의 할 때 스펙부터 보는데, 스펙이 없고 구현체만 있으면 메소드를 따로 골라서 봐야함.
    • 인터페이스를 따로 뽑는 게 구조를 잡기에는 유리

5. 결론

5.1 지금까지 다룬 이야기

  • 소프트웨어에서 아키텍처의 중요성
    • 소프트웨어는 변화함
    • 바꾸기 위해서는 읽고 이해해야 하는데, 읽기 좋고 수정하기 좋은 코드여야지 사용자에게도 더 빠르게 기능을 내보낼 수 있음
  • 좋은 아키텍처를 구성하는 방법
    • 많은 원칙들이 있는데, 그것들을 모두 다 따라하는 것은 어려우니 패턴을 추천
  • 클린 아키텍처
    • 계층을 나누고, 모든 계층은 더 중요한 쪽으로 의존성이 향해야 한다는 것이 핵심
  • 클린 아키텍처는 애매합니다.
    • 규칙이 단순하기 때문에 애매한데, 그것을 위한 기준들을 설명하였음

연사님 마무리 멘트
소프트웨어 아키텍처는 되게 중요한데 천시를 받고 있는 거 같다.
이 발표를 통해 중요하다는 걸 인지하고, 팀원들을 설득할 수 있을 정도가 되면 좋겠다.
클린 아키텍처가 태생적으로 애매한 부분이 있는데, 그 부분을 어떻게 결정하면 좋을지도 설명 드렸으니 클린 아키텍쳐 같이 했으면 좋겠다.

0개의 댓글