Featured image of post 15. 아키텍처란?

15. 아키텍처란?

5부 - 아키텍처

소프트웨어 아키텍트란?
소프트웨어 아키텍트는 프로그래머이며, 앞으로도 계속 프로그래머로 남아야하므로, 고수준 문제에만 집중하여 코드와 동떨어져서는 안 된다.

소프트웨어 아키텍트는 개발에 참여하며 나머지 팀원들이 생산성을 극대화할 수 있는 설계를 하도록 방향을 이끌어준다.

따라서 프로그래밍을 작업에 계속 참여하며 문제를 직접 경험하고 이를 통해 다른 프로그래머를 지원하는 작업을 수행해야한다.


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

시스템을 구축했던 사람들이 만들어낸 시스템의 형태로 컴포넌트로 분할하는 방법, 분할된 컴포넌트를 배치하는 방법, 컴포넌트가 서로 의사소통하는 방식에 따라 정해진다.

이러한 시스템 형태는 아키텍처 안에 담긴 소프트웨어 시스템이 쉽게 개발, 배포, 운영, 유지보수되도록 만들어진다.

개발, 배포, 운영, 유지보수를 용이하게 만들기 위해서는 가능한 한 많은 선택지를, 가능한 한 오래 남겨두는 전략을 따라야한다.


시스템 아키텍처는 시스템의 동작 여부와는 거의 관련이 없다.

  • 형편없는 아키텍처를 갖춤 시스템도 수없이 많지만, 그런데로 잘 동작한다.
  • 이러한 경우 대체로 운영에서는 문제가 없지만 배포, 유지보수, 계속되는 개발 과정에서 어려움을 겪는다.

시스템 아키텍처가 시스템이 제대로 동작하는 것과는 직접적으로 관련이 없지만, 시스템이 제대로 동작하도록 지원한다(간접적).

  • 시스템을 쉽게 이해할 수 있게 한다.
  • 쉽게 개발할 수 있게 한다.
  • 쉽게 유지보수할 수 있게 한다.
  • 쉽게 배포하게 해준다.

아키텍처의 주된 목적은 시스템의 생명주기를 지원하는 것이다. 궁극적으로 시스템의 수명과 관련된 비용은 최소화하고, 프로그래머의 생산성은 최대화하는 데 있다.

개발

시스템 아키텍처는 개발팀(들)이 시스템을 쉽게 개발할 수 있도록 뒷받침해야만 한다.

팀 구조

팀 구조가 다르다면 아키텍처 관련 결정에서도 차이가 난다.

  • 작은 규모
    • 팀 규모가 작아 상위 구조로 인한 장애물이 없기를 바라기 때문에 아키텍처 없이 시작하는 경우가 많다.
    • 잘 정의된 컴포넌트나 인터페이스가 없더라도 서로 효율적으로 협력하여 모노리틱 시스템을 개발할 수 있다.
    • 개발 초기에는 아키텍처 관련 제약들이 오히려 방해가 된다고 여길 가능성이 높다.
  • 큰 규모
    • 다른 요소를 고려하지 않는다면 아키텍처는 팀별 단일 컴포넌트(큰 관심사 별 컴포넌트)로 각각 발전될 가능성이 높다.
    • 팀별 단일 컴포넌트 아키텍처는 시스템을 배포, 운영, 유지보수하는 데 최적은 아닐 확률이 높다.
    • 시스템을 신뢰할 수 있고 안정된 인터페이스를 갖춘, 잘 설계된 컴포넌트 단위로 분리하지 않으면 개발이 진척되지 않는다.

배포

배포 비용이 높을수록 시스템의 유용성은 떨어진다.

따라서 소프트웨어 아키텍처는 시스템을 단 한번에 쉽게 배포할 수 있도록 만드는 데 그 목표를 두어야 한다.

  • 초기 개발 단계에서는 배포 전략을 거의 고려하지 않기 때문에 개발하기는 쉬워도 배포하기는 어려운 아키텍처가 만들어진다.

마이크로서비스 아키텍처 micro-service architecture

컴포넌트 경계가 매우 뚜렷해지고, 인터페이스가 대체로 안정화되므로 시스템을 매우 쉽게 개발할 수 있다.

하지만 늘어난 수많은 마이크로서비스로인해 서로 연결하기 위해 설정하고 작동 순서를 결정하는 과정에서 오작동이 발생할 원천이 스며들어 배포하기 어려워진다.


아키텍트가 배포 문제를 초기에 고려했다면, 더 적은 서비스를 사용하고, 서비스 컴포넌트와 프로세스 수준의 컴포넌트를 하이브리드 형태로 융합하며, 좀 더 통합된 도구를 사용해 상호 연결을 관리했을 것이다.

운영

아키텍처가 시스템 운영에 미치는 영향은 개발, 배포, 유지보수에 미치는 영향보다는 덜 극적이다.

운영에서 겪는 대다수의 어려움은 단순히 하드웨어를 더 투입해서 해결할 수 있다.

  • 소프트웨어 아키텍처가 비효율적이라면 스토리자와 서버를 추가하는 것만으로 제대로 동작하도록 만들 수 있을 때가 많다.
  • 하드웨어는 값싸고 인력은 비싸다.

운영 관점에서 소프트웨어 아키텍처는 비용 공식 관점에서 보다는 개발, 배포 유지보수 쪽으로 더 기운다는 의미를 가진다.

운영 방식

시스템 아키텍처가 개발자에게 시스템의 운영 방식을 잘 드러내 준다.

좋은 소프트웨어 아키텍처는 시스템을 운영하는 데 필요한 요구도 알려준다.

  • 유스케이스, 기능, 시스템의 필수 행위를 일급 엔티티로 격상시킨다.
  • 위 요소가 개발자에게 주요 목표로 인식되도록 해야한다.

이를 통해 시스템을 이해하기 쉬워지며, 따라서 개발과 유지보수에 큰 도움이 된다.

유지보수

유지보수는 모든 측면에서 소프트웨어 시스템에서 가장 많은 비용이 발생한다.

유지보수의 가장 큰 비용은 탐사 spelunking이로 인한 위험부담에 있다.

탐사란?

기존 소프트웨어에 새로운 기능을 추가하거나 결함을 수정할 때, 소프트웨어를 파헤쳐서 어디를 고치는 게 최선인지, 어떤 전략을 쓰는 게 최적일지를 결정할 때 드는 비용

변경사항을 반영할 때 의도치 않은 결함이 발생할 가능성은 항상 존재하며, 이로인한 위험부담 비용이 추가된다.

주의를 기울여 신중하게 아키텍처를 만들면 이 비용을 크게 줄일 수 있다.

  • 시스템을 컴포넌트로 분리
  • 안정된 인터페이스를 두어 서로 격리

이를 통해 미래에 추가될 기능에 대한 길을 밝혀 둘 수 있을 뿐만 아니라 의도치 않은 장재가 발생할 위험을 크게 줄일 수 있다.

선택사항 열어두기

책 초반에 언급했듯, 소프트웨어는 행위적 가치와 구조적 가치를 지니며, 아키텍처 관점에서 구조적 가치를 추구해야한다.

소프트웨어를 만든 이유는 기계의 행위를 빠르고 쉽게 변경하는 방법이 필요했기 때문인데, 이러한 유연성은 시스템의 형태, 컴포넌트의 배치 방식, 컴포넌트가 상호 연결되는 방식에 상당히 크게 의존한다.

소프트웨어의 유연성을 유지하는 방법은 선택사항(세부사항)을 가능한 한 많이, 가능한 한 오랫동안 열어두는 것이다.


정책과 세부사항

모든 소프트웨어 시스템은 정책과 세부사항으로 분해할 수 있다.

  • 정책
    • 모든 업무 규칙과 업무 절차를 구체화한다.
    • 시스템의 진정한 가치가 살아있는 곳
  • 세부사항
    • 사람, 외부 시스템, 프로그래머가 정책과 소통할 때 필요한 요소
    • 정책이 가진 행위에는 조금도 영향을 미치지 않는다.
    • 입출력 장치, DB, 웹 시스템, 서버, 프레임워크, 프로토콜 등

아키텍트의 목표는 시스템에서 정책을 가장 핵심적인 요소로 식별하고, 동시에 세부사항은 정책에 무관하게 만들 수 있는 형태의 시스템을 구축하는 데 있다.

이를 통해 세부사항을 결정하는 일은 미루거나 연기할 수 있게 된다.

예시

  • 개발 초기에는 데이터베이스 시스템을 선택할 필요가 없다.
    • 고수준의 정책을 데이터베이스가 관계형인지, 분산형인지, 계층형인지 등에 관계 없도록 만들어야 한다.
  • 개발 초기에는 웹 서버를 선택할 필요가 없다.
    • 고수준의 정책은 자신이 웹을 통해 전달된다는 사실을 알아서는 안 된다.
    • 웹 개발 기술들에 대해 고수준의 정책이 전혀 알지 못하게 만들면, 프로젝트 후반까지는 어떤 종류의 웹 시스템을 사용할지를 결정하지 않아도 된다.
    • 시스템을 웹을 통해 전송할 것인지조차도 결정할 필요가 없다.
  • 개발 초기에는 REST를 적용할 필요가 없다.
    • 고수준의 정책은 외부 세계로의 인터페이스에 대해 독립적이어야 한다.
  • 의존성 주입 프레임워크를 적용할 필요가 없다.
    • 고수준의 정책은 의존성을 해석하는 방식에 대해 신경써서는 안된다.

세부사항에 몰두하지 않은 채 고수준의 정책을 만들 수 있다면, 이러한 세부사항에 대한 결정을 오랫동안 미루거나 연기할 수 있다.

  • 이러한 결정을 더 오래 참을 수 있다면, 더 많은 정보를 얻을 수 있고, 이를 기초로 제대로 된 결정을 내릴 수 있다.
  • 선택사항을 더 오랫동안 열어 둘 수 있다면 더 많은 실험을 해볼 수 있고 더 많은 것을 시도할 수 있다.

좋은 아키텍트는 결정되지 않은 사항의 수를 최대화한다.

결론

좋은 아케텍트는 세부사항을 정책으로부터 신중하게 가려내고, 정책이 세부사항과 결합되지 않도록 엄격하게 분리한다.

이를 통해 정책은 세부사항에 관한 어떠한 지식도 갖지 못하게 되며, 어떤 경우에도 세부사항에 의존하지 않게 된다.

좋은 아키텍트는 세부사항에 대한 결정을 가능한 한 오랫동안 미룰 수 있는 방향으로 정책을 설계한다.