서비스는 프로세스나 플랫폼 경계를 가로지르는 함수 호출에 지나지 않는다. 아키텍처 관점에서 중요한 서비스도 있지만, 중요하지 않은 서비스도 존재한다.
이 장에서는 서비스 아키텍처의 장점에 대해 알아본다.
시스템을 서비스들로 분리하게 되면 서비스 사이의 결합이 확실히 분리된다.
하지만 네트워크 상의 공유 자원 때문에 결합될 가능성이 존재한다.
ex) 서비스를 오가는 데이터 레코드에 새로운 필드를 추가하게 되면 이 필드를 사용해 동작하는 모든 서비스는 반드시 변경되어야 한다. 이렇게 되면 서비스들은 이 데이터 레코드에 강하게 결합되고, 서비스 간에도 간접적 결합이 생긴다.
대규모 엔터프라이즈 시스템을 독립적으로 개발하고 배포 가능한 서비스를 이용하여 만들 수 있다.
하지만 서비스 기반 시스템 이외에도 다른 시스템으로 구축할 수 있기 때문에 서비스는 확장 가능한 시스템을 구축하는 유일한 방법이 아니다.
또한 결합 분리의 오류에 따르면 서비스라고 해서 항상 독립적으로 개발하고, 배포하며, 운영될 수 있는 것은 아니다.
위의 서비스에 야옹이를 배달하려는 서비스를 추가 하기 위해서는 전부 변경해야 한다.
-> 기능적으로 분해 되어 있기 때문
해당 서비스는 모두 결합되어 있기 때문에 독립적으로 개발, 배포, 유지가 불가능하다.
이것이 바로 횡단 관심사가 지니는 문제이다.
이 서비스와 같은 것처럼 종류의 기능적 분해는 새로운 기능이 기능적 행위를 횡단하는 상황에 취약하다.
이전 서비스는 컴포넌트 기반 아키텍처를 통해 해결 가능하다.
배차 관련 로직은 Rides 컴포넌트에, 야옹이 관련 로직은 Kittens 컴포넌트로 추출되었다.
이 두 컴포넌트는 기존 컴포넌트들에 있는 추상 기반 클래스를 템플릿 메서드나 전략 패턴을 통해 오버라이드 한다.
이러한 과정을 통해 야옹이 기능은 결합이 분리되며, 독립적으로 개발, 배포가 가능해진다.
서비스 또한 SOLID 원칙대로 설계할 수 있으며 컴포넌트 구조를 갖출 수 있어 기존 컴포넌트를 변경하지 않고도 새로운 컴포넌트를 추가할 수 있다.
ex) java 의 경우 jar 파일을 통해 기능을 추가하면 기존 jar 파일에 정의된 추상 클래스를 확장하여 만들어진다. 이를 통해 새로운 기능 배포는 개방 폐쇄 원칙을 준수하게 된다.
위의 그림은 각 서비스의 내부는 자신만의 컴포넌트 설계로 되어 있기 때문에 새로운 기능을 추가할 때 파생 클래스 생성을 통해 가능하다.
주요 시스템이 직면하는 횡단 관심사를 처리하기 위해서는 서비스 내부는 의존성 규칙도 준수하는 컴포넌트 아키텍처로 설계해야 한다.
아키텍처 경계는 서비스 사이에 존재하지 않으며, 아키텍처 경계를 정의하는 것은 서비스 내에 위치한 컴포넌트다.
서비스는 시스템의 확장성과 개발 가능성 측면에서 유용하지만, 아키텍처적으로 중요도는 떨어진다.
시스템의 아키텍처는 시스템 내부에 그어진 경계와 경계를 넘나드는 의존성에 의해 정의된다.
시스템의 구성 요소가 통신하고 실행되는 물리적 메커니즘에 의해 아키텍처가 정의되는 것이 아니다.