관심사의 분리란(Seperation Of Concern) 1편

승톨·2021년 12월 8일
9
post-thumbnail

관심사 분리, 클린코드 책을 보다가 Soc, AOP 라는 개념이 나와서 궁금해진 주제이다.

그래서 구글링을 해보다가 관심사의 분리를 high level 차원에서 잘 설명해준 아티클이 있어서 번역을 해보았다.

2008년에 쓰인 글이지만 지금 읽어도 충분히 좋은 글이라, 관심사 분리 공부할 분들에게 도움이 되리라 믿는다.

원문 : https://aspiringcraftsman.com/2008/01/03/art-of-separation-of-concerns/


Introduction

소프트웨어 엔지니어링 분야에서, 관심사의 분리(이하 SoC)는 시스템 내부에서 질서를 달성하기 위해 소프트웨어 요소의 상관관계와 설계를 적용하는 것이다. 적절한 SoC를 통해 복잡성은 관리 가능해진다.

이 아티클의 목표는 SoC의 원칙을 이해시키는 걸 돕고, 지속가능한 시스템 개발에 대해 소프트웨어 엔지니어들이 기본적인 컨셉들을 알 수 있게 제공하는 것이다.

The Principle of Separation of Concerns

SoC 법칙이란 시스템 요소가 단일 목적이고 배타성을 가져야 한다는 것을 명시한다. 그 말은, 어떤 요소도 다른 요소와의 책임을 공유하면 안 되고, 그 요소와 관계가 없는 책임을 포함시킬 수 없다는 것이다.

SoC란 경계를 세우는 것으로서 달성된다. 경계란 주어진 책임 세트를 설명하는 논리적이거나 물리적인 제한이다. 경계란 애플리케이션 내에 핵심 행동을 정의하는 메소드, 객체, 컴포넌트, 서비스 등 의 사용을 의미한다. 혹은 소스 구성에 대한 프로젝트, 솔루션, 폴더 구조를 포함하기도 한다.

혹은 구조를 짜기 위한 애플리케이션 레이어와 티어들을 포함하기도 하고, 프로덕트 릴리즈 구성에 필요한 버전화 되어있는 라이브러리나 설치 파일을 포함하기도 한다.

그러나 Soc를 달성하는 프로세스는 종종 책임 세트의 분리를 내포하기도 한다. 목표는 시스템을 분리되지 않는 파트들로 조각 내는 것이 아니라, 시스템을 반복되지 않고 응집력이 있는 책임들의 세트를 가진 요소들로 구성하기 위함이다.

Albert Einstein이 얘기했듯이 '가능한 모든 것들을 단순하게 만들어라. 더 단순하게가 아니라.'

핵심은, SoC는 질서에 관한 것이다. SoC의 종합적인 목표는 각각의 파트가 의미있고 직관적인 롤을 수행하지만 변화에 적응하는 능력을 극대화시킨, 잘 조직된 시스템을 설립하는 것이다.

The Value of Separation of Concerns

소프트웨어 디자인에 SoC의 법칙을 적용하는 것은 여분의 혜택들을 만들 수 있다.

첫번째로 개별 컴포넌트의 복제가 없어지고, 목적이 단일화되어 전체 시스템을 유지보수하기 쉽게 만든다.

두번째, 시스템 전체가 유지보수성이 올라감으로써 생겨난 부산물로 인해 더 안정적이게 된다.

세번째, 각각의 컴포넌트가 응집력 높은 단일 책임으로 자신의 관심사만 챙기게 요구되는 전략들은 자연스러운 확장 가능성들을 낳는다.

네번째, 컴포넌트들을 단일 목적에 집중할 수 있게 요구됨으로써 생기는 디커플링은 컴포넌트들이 다른 시스템, 혹은 같은 시스템 내의 다른 컨텍스트에서 더 쉽게 사용되게 만든다.

다섯번째, 유지보수성과 확장가능성의 증대는 시장성과 (시장에서의) 시스템 채택률에 큰 영향을 줄 수 있다.

또한 SoC 원칙은 비즈니스 조직에 적용할 때도 이익을 줄 수 있다.

대기업 내부에서, 그룹들과 서브 조직들이 응집력 있는 고유한 책임 세트를 할당 받는 걸 보장하는 것은

  • 팀 간의 필요한 협력을 최소화 시키고,
  • 각 팀이 그들 공동의 책임과 핵심 경쟁력에 집중할 수 있게 그들의 잠재력을 최대로 끌어올림으로써

전체 비즈니스 목표 달성을 용이하게 만드는걸 돕는다.

SoC 원칙은 또한 회사 전체 시스템 내의 문제 해결력을 향상 시킨다. 책임이 적절하게 기술되어 있을 때 문제를 파악하는 것은 쉬워지고, 해결은 더 빨라지고, 직원의 책임은 높아진다.

결국 각각의 그 영역들은 통제 프로세스의 퀄리티를 올리는데 기여한다.

조직이나 소프트웨어 시스템이라는 관점에서 SoC 원칙을 적용하는 것은 불필요한 복제를 제거하고 적절한 책임 할당을 통해 복잡도를 관리하는데 도움을 줄 수 있다.

다음 섹션에서는 애플리케이션 디자인에 관련된 SoC를 달성하기 위한 여러가지 테크닉에 대해 얘기해볼 것이다.

Horizontal Separation

수평적 SoC는 애플리케이션 내에 동일한 롤을 수행하는 기능의 논리적 레이어 단위로 앱을 분리하는 프로세스를 말한다.

GUI 애플리케이션들이 공통적으로 분리하는 케이스는 Presentation, Business, Resource Access 레이어로 이뤄진 분리이다.

이런 카테고리 레이어들은 대부분의 애플리케이션이 필요한 주요 타입의 관심사를 포함하고 있고, 애플리케이션 내에 의존성 레벨을 최소화 하는 관심사 구성에 해당한다.

Figure1은 3개의 레이어로 나눠진 애플리케이션을 묘사한다.

Presentation 레이어는 애플리케이션의 UI와 관련된 컴포넌트와 프로세스들을 포함한다.

이 레이어는 애플리케이션의 시각적 디스플레이를 정의하는 컴포넌트들을 포함하고, controller나 presenter나 presentation model 같은 고도화된 디자인 컨셉을 포함할 수 있다.

Presentation 레이어의 주요 목표는 애플리케이션 도메인이 독립적으로 다변화 될 수 있게 하기 위해 모든 UI 관심사를 캡슐화 하는 것이다.

이 레이어는 오직 필요한 시각적 디스플레이와 관련된 프로세스와 컴포넌트들만 포함해야 한다.(그 외 다른 컴포넌트와 프로세스는 배제 해야 한다.)

이것은 애플리케이션 내의 다른 레이어가 그 앱의 디스플레이 관심사로부터 독립적으로 벗어날 수 있게 하는 것이다.

Business 레이어는 애플리케이션 도메인과 관련된 컴포넌트와 프로세스를 포함한다.

이 레이어는 객체 모델을 정의하고, 비즈니스 로직을 다루고, 시스템의 워크플로우를 통제하는 컴포넌트들을 포함한다.

Business 레이어는 시스템 내의 워크플로우, 비즈니스 프로세스, 엔티티를 나타내는 전문화된 컴포넌트들을 통해 표현될 수 있다. 혹은 데이터와 행동을 캡슐화한 전통적인 객체 지향 도메인 모델을 통해 표현될 수도 있다.

이 레이어의 주요 목표는 애플리케이션 전용으로 핵심적인 비즈니스 관심사(어떻게 데이터와 행동이 노출되거나, 어떻게 데이터가 명확하게 받아지는지)를 캡슐화하는 것이다.

Business 레이어는 애플리케이션의 비즈니스 도메인과 관련된 컴포넌트들과 프로세스들만 오직 포함해야만 하고, 그 외 다른 컴포넌트와 프로세스는 배제해야 한다.

Resource Access 레이어는 외부 정보 접근과 관련된 컴포넌트와 프로세스들을 포함한다.

이 레이어는 로컬 데이터 스토어나 외부 서비스 인터페이스를 가진 컴포넌트를 포함한다.

Resource Access 레이어의 목표는 데이터 접근에 대한 상세 사항에 관해 추상화 시켜 레이어로 제공하는 것이다.

이 레이어는

  • 데이터베이스 설정
  • 서비스 연결
  • 데이터베이스 스키마나 stored procedure, 서비스 프로토콜에 대한 개념, 서비스 엔티티들과 비즈니스 엔티티의 데이터를 마샬링 하는 것 같은 개념에 대해 유지보수하는 것,

등의 작업을 포함한다.

Resource Access 레이어는 시스템에 대해 외부 데이터 접근과 관련된 컴포넌트와 프로세스만 오직 포함해야 한다. 그 외 다른 컴포넌트와 프로세스는 배제해야 한다.

서비스 지향 애플리케이션에 사용되는 또 다른 통상적인 분리는 애플리케이션을 Service Interface, Business, Resource Access 레이어로 분리하는 것이다.

이런 분리에서는, Business와 Resource Access 레이어는 이전에 서술한 내용(Presentation, Business, Resource Access 레이어) 처럼 같은 목적을 제공한다. 서비스 노출에 대한 관심사는 Service Interface 레이어로 캡슐화 된다.

이 Service Interface 레이어는 (다양한 프로토콜, 서비스 특화된 계약 관리와 데이터 타입을 통한 비즈니스 프로세스들의 노출 같은) Service Interface 관심사를 포함한다.

Service Interface 레이어의 주요 목표는 애플리케이션 도메인을 독립적으로 변화시킬 수 있게 하기 위해 모든 Service Interface 관심사를 캡슐화 하는 것이다.

Service Interface 레이어는 오직 서비스로서의 애플리케이션 노출과 관련된 컴포넌트와 프로세스들을 포함해야 한다. 그 외 다른 컴포넌트와 프로세스들은 배제해야 한다.

애플리케이션 내에서 그들의 역할에 기초한 관심사 프로세싱을 그룹화 함으로써, 전체적인 시스템 관리 가능성 향상이라는 많은 이점이 생긴다.

이런 이점들은

  • 변경에 대한 적응력 향상,
  • 변경에 대한 임팩트,
  • 재사용 가능성 상승

등에서 얻을 수 있는 일관된 아키텍쳐, 프로세스의 고립, (객체)격리를 통한 유지보수의 난이도 하락을 포함한다.

Vertical Separation

관심사에 대한 수직적 분리는 애플리케이션을 (애플리케이션 내의 동일한 피쳐나 서브 시스템과 관련된) 기능 모듈로 분리하는 프로세스를 뜻한다.

수직적 분리는 전체 관점에서 애플리케이션의 기능들을 분리하고, 단일 경계 내에서 interface, business, resource access 관심사를 결부시킨다.

Figure3은 3가지 모듈로 애플리케이션 분리한 걸 묘사한다.

애플리케이션의 기능을 모듈 단위로 분리하는 것은 각 기능의 의존성과 책임을 분명하게 만든다. 이것은 테스팅과 전반적인 유지보수를 도와준다.

경계들은 구조를 논리적으로 잡을 수 있게 도움을 주고, 독립적인 개발과 유지 보수를 물리적으로 가능하게 해준다.

논리적 경계는 모듈성의 존재에 대해 암시를 해주지만, 분리를 나타내기 위해 사용되는 메소드들은 애플리케이션의 실제 배포나 런타임 행위에 대해선 아무런 관련이 없다.

이건 애플리케이션의 유지보수성을 향상시키는데 도움을 줄 수 있다. 마찬가지로, 물리적으로 기능을 분리하기 위한 미래의 노력을 경감시켜주기도 한다.

Figure4는 논리적 경계를 담은 애플리케이션을 묘사한다.

물리적 경계는 일반적으로 add-in(확장 프로그램)이나 종합적인 애플리케이션을 개발하는 맥락에서 사용된다.

또한 기능들이 서로 다른 개발 팀에 의해 관리될 수 있게 해준다.

add-in 모듈을 탑재하는 애플리케이션들은 종종 auto-discovery 같은 테크닉을 이용하거나, 외부 config 소스에 기초한 모듈을 초기 설정한다.

Figure5는 서로 다른 개발팀에 의해 개발된 모듈들을 탑재한 호스팅 프레임워크를 묘사한다.

수직적 분리가 애플리케이션 내의 특정 기능의 수행에 연관된 관심사 세트들로 앱을 분류하긴 하지만, 이것이 관심사 전략의 다른 분리 기법 사용을 배제하는 것은 아니다.

예를 들어, 각각의 모듈은 그 자체가 (모듈 내에서 컴포넌트의 역할을 설명하기 위해) 레이어를 사용하게 설계되어 있다.

Figure6는 관심사의 수평적, 수직적 분리를 둘다 사용하는 애플리케이션을 묘사한다.

Aspect Separation

관점 지향 프로그래밍으로 더 잘 알려진 관심사의 관점 분리는 애플리케이션의 핵심 관심사에서 나온 애플리케이션의 횡단 관심사(cross-cutting concerns)를 분리하는 프로세스를 뜻한다.

횡단 관심사 혹은 관점은 애플리케이션 내에 여러 경계를 가로지르며 심어지는 관심사를 의미한다.

Logging은 많은 시스템 컴포넌트를 가로지르며 수행되는 활동(횡단 관심사)의 한 예시라고 볼 수 있겠다.

횡단 관심사는 애플리케이션 도처에 널리 퍼져서 사용되기 때문에 유지보수가 어려워질 수 있다. 핵심 관심사와 섞이게 되면 복잡도가 증가하고, 애플리케이션을 더 유지 보수하기 어렵게 만든다. 그런 관심사들을 분리함으로써, 핵심 관심사들과 횡단 관심사들 모두 더 관리하기 쉬워진다.

관점 분리는 횡단 관심사들의 전처리(pre-processing), 컴파일 타임, 런타임의 결합에 의존한다는 점에서 다른 분리 기법과 차이가 있다.

두개의 관심사를 다시 결합시키는 프로세스를 weaving이라고 한다.

다양한 전략을 사용함으로써, 횡단 관심사는 애플리케이션 내에서 런타임 결합을 위해 분리 될 수 있고, 다시 weave 될 수도 있다.

관점 분리 도구들은 여러 프로그래밍 언어에서 사용 가능하다.

관점 분리를 쉽게 하기 위해 사용 할 수 있는 툴 리스트 등의 정보를 보려면, Aspect-Oriented Programming 를 참고해라.

profile
소프트웨어 엔지니어링을 연마하고자 합니다.

1개의 댓글

comment-user-thumbnail
2022년 7월 24일

잘 읽고 갑니다😊

답글 달기