개발서적

[클린 아키텍처] 5부. 아키텍처 - 1

GaGah 2022. 1. 26. 01:19

출처 : yes24

 

 

 소프트웨어 아키텍트란?

바로, 프로그래머이며 앞으로도 계속 프로그래머로 남는다. 
즉, 프로그래밍을 지속적으로 이어가고 생산성을 극대화할 수 있는 설계를 하도록 방향을 이끌어주는 역할을 한다.

 

 소프트웨어 시스템의 아키텍처란?

시스템을 구축했던 사람들이 만들어낸 시스템의 형태
이 형태는 아키텍처 안에 담긴 소프트웨어 시스템이 쉽게 개발, 배포, 운영, 유지보수되도록 만들어진다.
아키텍처의 궁극적인 목표는 시스템의 수명과 관련된 비용을 최소화하고, 프로그래머의 생산성은 최대화하는 데 있다.

 

❗ 아키텍처를 설계할 때, 중요하게 생각해야 할 것

1) 개발 

  • 상위 구조로 인한 장애물이 없기를 바라지 말고, 시스템을 신뢰할 수 있고 안정된 인터페이스를 갖춘, 잘 설계된 컴포넌트 단위로 분리하자.

2) 배포 

  • 배포의 비용을 최대한 줄이고, 한 번에 쉽게 배포할 수 있도록 만들어야 한다.

3) 운영 

  • 개발, 배포, 유지보수 보다 덜 중요하긴 하지만, 시스템을 운영하는 데 필요한 요구도 알려준다.
  • 시스템 아키텍처를 통해 개발자가 시스템의 운영 방식을 잘 알도록, 즉, 주요 목표로 인식되도록 해야 한다.

4) 유지보수

  •  모든 측면으로 봤을 때, 비용이 가장 많이 듦.
  • 어떤 변경사항을 반영할 때,의도치 않은 결함이 발생할 가능성은 항상 존재하며, 이로 인한 위험부담 비용이 추가된다.

5) 선택사항을 가능한 한 많이 열어두기

  • 소프트웨어를 만든 이유는 기계의 행위를 빠르고 쉽게 변경하는 방법이 필요했기 때문 (=유연성)
  • 중요하지 않은 세부사항을 가능한 한 오랫동안 열어두자
  • 정책(시스템의 진정한 가치)를 가장 핵심적인 요소로 식별하고, 세부사항(=사람,외부 시스템 등)은 정책에 무관하게 만들 수 있는 형태의 시스템을 구축.
    • 예) 개발 초기에 데이터베이스가 관계형인지, 분산형인지, 계층형인지, 평범한 플랫 파일인지와 관련이 없도록 만들어야 한다.
    • 즉, 세부사항에 몰두하지 않은 채 고수준의 정책을 만들자. 

6) 장치 독립성

  • 어떤 장치를 사용할지 전혀 모른채, 그리고 고려하지 않고도 프로그램을 작성할 수 있음.
  • 운영체제는 입출력 장치를 소프트웨어 함수로 추상화된 단위 레코드 장치를 처리한다.
  • 동일한 프로그램을 아무런 변경 없이도 카드에서 읽고 쓸 수 있다.
  • 개방 폐쇄 원칙의 탄생

 

➰ 좋은 아키텍처는 "이것"을 지원해야 한다.

1) 유스케이스

시스템의 의도를 지원해야한다.
  • 만약 시스템이 장바구니 애플리케이션이라면, 장바구니와 관련된 유스케이스를 지원해야한다.
  • 좋은 아키텍처는 행위를 명확히 하고 외부로 드러내며, 이를 통해 시스템이 지는 의도를 아키텍처 수준에서 알아볼 수 있도록 만드는 것

 

2) 운영

더 실질적이며 덜 피상적인 역할을 맡는다.
  • 시스템이 초당 100,000명의 고객을 처리해야 한다면, 아키텍처는 이 요구와 관련된 처리량과 응답시간을 보장해야 한다.
    • 이런 처리를 가능하게 하는 방법은 열어두어야 한다. (ex. 수많은 서버가 병렬로 실행 / 단일 프로세스만 동작 등 )

 

3) 개발

콘웨이 법칙? 
-> 시스템을 설계하는 조직이라면 어디든지 그 조직의 의사소통 구조와 동일한 구조의 설계를 만들어 낼 것이다. 
  • 각 팀이 독립적으로 행동하기 편한 아키텍처를 반드시 확보하여 개발하는 동안 팀들이 서로 방해하지 않도록 해야한다.

 

4) 배포

  • 수십 개의 작은 설정 스크립트나 속성 파일을 약간씩 수정하는 방식을 사용하지 않는다.
  • 좋은 아키텍처라면 시스템이 빌드된 후 즉각 배포할 수 있도록 지원해야 한다.

 

5) 선택사항 열어놓기

  • 향후 시스템에 변경이 필요할 때, 어떤 방향으로든 쉽게 변경할 수 있도록 한다.

 

 

🐕 결합과 분리

어떤 시스템의 유스케이스 전부를 알 수 없지만, 어떤 "역할"을 하는 시스템인지는 알 수 있다.

따라서, 아키텍트는 단일 책임 원칙과 공통 폐쇄 원칙을 적용하여 의도의 맥락에 따라서 다른 이유로 변경되는 것들은 분리하고, 동일한 이유로 변경되는 것들은 묶는 것이 핵심

  • 서로 다른 이유로 변경?
    • ex1) 사용자 인터페이스 : 업무 규칙과는 아무런 관련이 없다.
      좋은 아키텍처라면? UI와 업무 규칙을 분리.
    • ex2) 입력 필드 유효성 검사 vs 이자 계산/재고품 집계 규칙
      어떤 규칙이 언제 바뀔지 모르기 때문에, 서로 분리하는 것이 좋다.
      즉, 독립적으로 변경할 수 있도록 하자.

    • ex3) 유스케이스
      주문 입력 시스템에서 주문을 추가하는 유스케이스 vs 주문을 삭제하는 유스케이스
      입력/삭제 각각의 UI, 데이터베이스, 업무규칙(로직) 등 각 계층에서 서로 겹치지 않도록 분리하자.

 

이렇게, 분리하면 좋은 점은?

  • 운영 시, 큰 도움이 된다.
    높은 트래픽, 낮은 트래픽이 있는 서비스들도 모두 분리가 되어있을 것이고, 높은 트래픽을 요구하는 유스케이스의 경우 여러 서버로 복제하여 실행할 수 있다.
  • 위와 같은 작업을 하기 위해서는 마이크로 서비스(=서비스 지향 아키텍처, SOA)가 되어야 한다. 

하지만, 이 모든 것도 다 선택권을 열어두어야 좋은 아키텍처이다.

 

 

결합/분리하는 방법

1) 소스 수준 분리 모드

소스코드 모듈 사이의 의존성을 제어할 수 있다.

이를 통해 하나의 모듈이 변하더라도 다른 모듈을 변경하거나 재컴파일하지 않도록 만들 수 있다.

 

2) 배포 수준 분리 모드

jar파일, DLL, 공유 라이브러리와 같이 배포 가능한 단위들 사이의 의존성을 제어할 수 있다.

이를 통해 한 모듈의 소스 코드가 변하더라도 다른 모듈을 재빌드하거나 재배포하지 않도록 만들 수 있다.

 

3) 서비스 수준 분리 모드

의존하는 수준을 데이터 구조 단위까지 낮출 수 있고, 순전히 네트워크 패킷을 통해서만 통신하도록 만들 수 있다. 

이를 통해 모든 실행 가능한 단위는 소스와 바이너리 변경에 대해 서로 완전히 독립적이게 된다.

ex) 마이크로 서비스 

 

 

개발/배포 독립성

  • 결합/분리가 잘 이루어진 아키텍처는 개발/배포에 있어 유연성이 생긴다.

 

📍 중복

진짜 중복인지, 가짜 중복인지 구별할 필요가 있다.

코드를 작성하면서 중복은 피해야할 나쁜 것이지만, 가짜 중복이 존재한다.

현재는 우연하게 중복일 수도 있지만, 시간이 지나면서 서로 다른 방향으로 분기하여 변경될 가능성이 있는 지 파악하자.

나중에 코드를 다시 분리하느라 큰 수고를 감수해야할 수도 있다.

LIST