[번역] 프레젠테이션, 도메인, 데이터 레이어링 Develop Tip

여러 책의 저자일 뿐만 아니라 개발 방법론 등 다양한 분야에서
중요한 역할을 하고 있는 Martin Fowler란 분이 있습니다.

한달 전 쯤 아주 관심있게 바라보고 있는 분야에 대해서
실제 어려움도 겪고 있던 것에 대한 아주 깨끗한 통찰력을
바라볼 수 있는 글이 있어 틈틈히 번역을 해 보았습니다.

MVC 모델링 및 프레임워크를 적용하다보면
팀간에 발생할 수 있는 마찰 이라던가 하는 부분을 짚었는데
실제로 겪어보지 못하나 알 수 없는 부분인데 잘 기술해 놓았더군요.


번역한 내용입니다.

Presentation Domain Data Layering
Martin Fowler 2015/08/26

아마도 컴퓨터 프로그램을 모듈화 하는 가장 일반적인 방법은
프레젠테이션 (UI), 도메인 로직 (또는 비즈니스 로직) 그리고 데이터 접근과 같은
세 가지 큰 영역으로 나누는 것입니다. 그래서 웹 응용 프로그램이
http 요청을 처리하고 HTML을 렌더링하는 웹영역과 어떤 계산이나 검증과 같은
비즈니스 로직을 처리하는 레이어 그리고 데이터베이스나 원격 서비스에 있는
데이터를 어떻게 처리하고 정렬하는 등의 데이터 접근 레이어로 나뉘는 것을
흔히 볼 수 있습니다.


대부분의 경우에 있어서 이런 방식의 모듈화는 권장되기도 하고 자주
사용하고 있기도 합니다. 적어도 제게 있어서 이 방식의 가장 큰 장점은
세가지 레이어에 따라 서로 독립적으로 바라볼 수 있게 영역을 분리하는 것입니다.
도메인 로직 코드를 작성하고 있는 동안에는 거의 UI 자체에 대해서는 신경쓰지 않아도 되고
데이터를 주는 데이터 소스 레이어와는 원하는 인터페이스로 상호 연동한다고 하고 
프로그램을 합니다. 데이터 접근 레이어의 작업을 진행할 때에는 그런 인터페이스에서
제공하기로 되어 있는 상세 기능에 대해서만 신경을 씁니다. 반면 프레젠테이션 레이어를
작업할 때는 UI의 동작에 집중하며 UI에서 보여주는 데이터 등은 마법과 같이
함수 호출에 의해서 이루어 집니다. 이런 방식으로 각각의 구성 요소를 구분함으로써
각 단계에 대한 사고 영역을 국한시킬 수 있고, 따라서 필요에 따라 하고자 하는 일을
좀 더 쉽게 할 수 있습니다.

이와 같은 영역의 제한이 어떤 프로그램의 절차 및 분리를 의미하지는 않습니다. 차라리
각 레이어 간에 일련의 연관 작업이 있음을 발견하기도 합니다. 최초에 UX와 도메인 및
데이터 레이어 등이 나누어 구성하였다 하더라도 UX를 다듬다 보면 도메인 레이어 부분을 
수정할 수도 있고 더 나아가 데이터 레이어 까지 변경될 수도 있습니다. 그러나 이와 같은
레이어를 넘나드는 작업을 할때에도 실제 변경 시에는 한번에 하나의 레이어에 집중하여
작업하는 것이 더 효율적임을 발견합니다. 이것은 두개의 모자로 리팩토링하는 것과 동일한
방법으로 모드를 스위칭 하는 것과 같습니다.
<역자주: 프로그램을 할 때 끊임없이 해당 함수나 영역을 리펙토링 하는 것과 새로운 함수를
 추가하는 것을 동시에 수행할 수는 없고 항상 스위칭을 하면서 작업해야 함.
 http://martinfowler.com/articles/workflowsOfRefactoring/#2hats>

모듈화를 하는 또 다른 이유는 각 모듈을 서로 다른 구현체로 대치할 수도 있다는데
있습니다. 이런 분리를 통하여 도메인 로직을 매번 복사하지 않고도 하나의 동일 도메인
로직에 여러 개의 프레젠테이션 레이어를 만들 수 있습니다. 여러 개의 프레젠테이션은
웹 응용에서 서로 다른 페이지가 될 수도 있거나 웹 응용 페이지에 모바일 응용의 페이지가
될 수 있습니다. 심지어는 스크립트 작성을 위한 API 또는 고전 방식의 CLI 명령이
될 수도 있습니다. 데이터 소스 레이어의 모듈화는 데이터베이스 기술 변화에 잘 대응하도록
하거나 주의를 깊이 기울이지 않아도 영구 자료를 저장하는 서비스를 제공하도록 할 수도
있습니다. 그러나 실제로 데이터 접근 모듈의 교체가 데이터 소스 레이어를 분리하기 위한
드라이버를 교체한다고 종종 들어왔지만 실제로 그렇게 제대로 했다는 말은 잘 들어보지 못했습니다.

모듈화는 또한 셀프 테스팅 코드와 같은 시험 가능성을 높여줍니다. 각 모듈의 경계는
테스트를 위한 중요한 단서를 제공합니다. UI 코드는 때때로 시험하기에 까다롭기 때문에
보다 쉽게 테스트 할 수 있는 도메인 레이어의 로직 코드만을 별도로 테스트 하는 것이 쉽습니다.
데이터 접근 레이어는 때때로 느리거나 이상한 결과를 보내줄 수도 있기 때문에 TestDoubles
방법을 이용하는 것이 보다 쉽고 잘 반응하도록 할 수 있습니다.
<역자주: TestDoubles는 테스팅 목적으로 여러 객체나 모듈 등을 간단한 테스트 대체품
 (dummy, fakes, stubs, spies, mocks)으로 바꾸면서 테스트 하는 것을 의미합니다.
 http://martinfowler.com/bliki/TestDouble.html>

레이어로 구분하는 것이 지금까지 설명한 대체 및 테스트 용이성 말고도 그 자체적인 의미를
지니는데 처음 이야기 한 것과 같이 레이어가 여러 개 되더라도 특정 레이어에 집중하여
살펴볼 수 있다는 것 자체 만으로도 의미를 지닌다 할 수 있습니다.

위와 같은 구성을 살펴볼 때 프레젠테이션-도메인-데이터 한가지 패턴 로 볼 수도 있고
프레젠테이션-도메인, 도메인-데이터 의 두 가지 패턴으로 볼 수도 있습니다. 제가 보기에는
프레젠테이션-도메인, 도메인-데이터 패텅의 절충안으로 프레젠테이션-도메인-데이터을
이용한다고 보입니다.

세 가지 레이어는 모듈의 형태로 생각할 수 있으며 이것은 소프트웨어를 상대적으로 독립된
형태로 결합하는 한 방식이라 할 수 있습니다. 실제로 어떻게 코드를 작성할 것인가 하는 것은
우리가 작성하는 프로그래밍 환경에 따라 달라집니다. 하지만 보통 서브루틴이나 함수와 같은
가장 작은 단위의 코드 집합이라고 생각합니다. 객체 지향 프로그래밍 환경에서는 클래스와
함수, 그리고 데이터 구조 등이 될 수 있겠지요. 최근 대부분의 언어는 계층 구조를 표현할 
수 있는 패키지나 네임스페이스라하는 좀 더 상위 레벨의 형식을 지원하는 경우가 많습니다.
모듈은 반드시 그렇지는 않지만 라이브러리 또는 서비스와 같은 배포 가능한 독립 유닛에 대응합니다.

레이어로 나누는 작업은 어느 단계에서도 일어날 수 있습니다. 작은 프로그램이라도 레이어에 따라
다른 파일의 개별 함수로 분리될 수 있습니다. 보다 큰 시스템은 많은 클래스를 담고 있는 네임스페이스의
레이어로 구성될 수도 있습니다.

지금까지 세 개의 레이어를 언급했지만 실제 아키텍쳐는 3개 이상의 레이어로 구성될 수도 있습니다.
일반적인 구성으로는 프레젠테이션과 도메인 레이어 사이에 서비스 레이어를 두는 방법이 있습니다.
또는 프레젠테이션 레이어를 프레젠테이션 모델과 같은 여러 개의 개별 레이어로 구성할 수도 있습니다.
더 많은 레이어 구성이 된다 해서 그 기본 구성이 바뀌지는 않기 때문에 코어 구성은 여전히 존재합니다.
<역자주: 프레젠테이션 모델은 인터페이스 사용되는 GUI 컨트롤을 독립적으로 표출하는 상태나 행위를
 나타냅니다. http://martinfowler.com/eaaDev/PresentationModel.html>


일반적으로 의존성은 레이어 스택에서 상단에서 하단으로 존재합니다. 프레젠테이션 레이어는 도메인 레이어에
따라 달라집니다. 또한 도메인 레이어는 데이터 레이어에 따라 달라집니다. 일반적인 좀 더 다른 구성 중에
하나는 데이터 소스 레이어와 도메인 사이에 맵퍼를 둠으로써 도메인 레이어가 데이터 소스에 의존적인지
않도록 하는 방법도 있습니다. 이런 접근 방법을 육각 아키텍쳐 라고 부르기도 합니다.
<역자주: 육각 아키텍쳐(Hexagonal Architecture) 
 http://alistair.cockburn.us/Hexagonal+architecture>

비록 프레젠테이션-도메인-데이터의 분리가 일반적인 방법이라 하더라도 상대적으로 작은 단위의 시스템에서
적용되기 시작합니다. 응용 프로그램이 커지면 커질 수록 각각의 레이어가 복잡해지고 또 그 레이어의
모듈화가 필요할 수도 있습니다. 이같은 경우에는 더 큰 상위 단계의 모듈로서 또 프레젠테이션-도메인-데이터의
구성을 하는 것이 어렵습니다. 종종 프레임워크들은 최상위 모델의 네임스페이스에서 뷰-모델-데이터와 같은
구성을 따르는 경향이 있습니다만 작은 시스템에서는 물론 상관없습니다. 대신 더 큰 시스템에서
이런 레이어가 너무 크게 되는 경우에는 내부적으로 자체 레이어로 나뉘는 도메인 기반의 모듈로써
분리를 하는 것이 좋습니다.


이렇게 레이어를 나누면서 조심할 것이 있는데 바로 개발 팀을 각각 세 개의 레이어 별로 구분하여 구성함으로써
처음 생각과는 달리 일이 꼬여버리는 것입니다. 이렇게 개발팀을 구분하는 것은 프론트엔드와 백엔드 개발이 서로 다른 프레임워크로 만들어져 있고 심지어는 서로 다른 프로그래밍 언어를 이용하기 때문에 당연한 것처럼 보이기도 합니다. 유사한 기술을 가진 사람들을 서로 모아 기술을 공유하고 같은 팀을 구성하는 것 말이지요.
마찬가지로 데이터베이스 전문가들만 모여 데이터 레이어를 구성하는 팀만을 꾸릴 수도 있습니다.
그러나 레이어로 나누어 작업되는 것은 다른 레이어들 사이에 긴밀한 상호 교류에 의하여 일이 이루어 진다는
것을 명심해야 합니다. 서로 서로 다른 레이어에 대한 이해를 공유해야 한다는 의미입니다. 만약 하나의 팀에서
각 레이어에 정통한 전문가들이 모여 있다면 그런 레이어의 상호 협조 부분이 더 쉬워질 것입니다.
하지만 팀의 경계가 시스템의 중요한 계층 간 이해를 개발하기 위한 개인의 의욕을 감소시킬 뿐만 아니라, 상당한 마찰을 추가 할 수 있음을 주의해야 합니다. 이렇게 팀을 나누는데 더욱 안 좋은 케이스는 개발자와
이용자 간의 거리만 더 넓히는 경우입니다.
결론적으로 개개의 개발자들이 꼭 풀스택 영역을 개발할 필요는 없다고 하더라도 각각의 팀은 풀스택 개발이
가능해야 합니다.



어느 분께는 도움이 되셨기를 ...

핑백

  • 지훈현서 : [고찰] 반려동물과 가축의 DevOps에 대한 고찰 2017-08-16 17:29:47 #

    ... , API 서버, DB Access, 저장소 등으로 잘게 나누어 놓고 서로 서로 유기적으로 묶이도록 함으로써 결국 가축 서버 형식을 구성했다 할 수 있겠습니다. (해당 블로그 참조) 제가 보기에 기존에 수없이 많은 회사 (특히 역사가 오래된 경우 일 수록)가 이런 반려동물 서버 식의 구조 및 개발 운영인 상태에서 기존의 모든 소스를 ... more

  • 지훈현서 : [Docker] Swarm stack for compose 2019-06-19 11:40:34 #

    ... 될지잘 모르는 상화이었죠. 그런데 말입니다, docker로 개발을 할때 다음과 같은 수순을 밟습니다. 1) Presentation, BackEnd logic, Data Access 레이어로 크게 나누어 설계 합니다.2) 큰 부분을 다시 작은 MSA 구성을 나눕니다.3) 일반적으로 하나의 MSA 구성의 결과는 하나의 Do ... more

덧글

  • 밀리네스 2015/09/11 18:06 # 답글

    저도 요즘 제가 꽤나 신뢰하는 Release It의 저자인 나이가드가 쓴 http://www.michaelnygard.com/blog/2015/04/bad-layering/ 에서 Layering에 대한 이야기를 읽고 고민중이였는데, 좋은 참고가 되었습니다^^

    사실 모듈화 라는 측면에서 microservice vs monolith 도 전개 되는데 http://martinfowler.com/bliki/MonolithFirst.html 라는 글과 http://martinfowler.com/articles/dont-start-monolith.html 이 서로 엇갈린 의견이 되기도 하고 해서 요즘에 참 고민이 많네요
  • 지훈현서아빠 2015/09/11 20:54 #

    좋은 의견 감사드립니다~~~ ^^
  • 지훈현서아빠 2015/09/14 11:32 #

    대충 알려주신 링크의 글을 읽어 보았는데요, 모놀리틱 구조이던 아니던 구조화 중에서 제일 중요한 부분은
    결국 도메인 로직인 것 같습니다. 어느 부분을 하던지 도메인에 특화된 이 로직은 빠질 수 없겠지요.
    이것이 모놀리틱이던 마이크로서비스던지 하는 것은 어떻게 인터페이스를 구성하는가 하는 문제이고,
    이것을 하단의 저장소와 붙이고 UI 하고 붙이고 하는 등의 구조화를 그 다음에 이루어 가면 될 것 같습니다.
    이것을 느슨하게 쉽게 수정하도록 개발방법론이 구성되면 애자일 이라고도 부르겠고,
    방법론에 따라 칸반 카드로 일을 해도 되구요...
    아님 더 궁극적으로는 지속적통합(CI) 또는 DevOps 를 어느 풀스택 개발팀이던
    (컨테이너를 사용하던 안하던)지 매력적으로 자신에 맞게 구성하는 것이 중요할 것 같습니다.

    이상 블루그 주인장의 간단한 생각이었습니다~ ^^
댓글 입력 영역

구글애드텍스트