Eternity's Chit-Chat

aeternum.egloos.com



진화적인 설계-3.ACCOUNTING 패턴 1부 Evolutionary Design

패턴을 알아낸다는 것은 다음에 무슨 일이 일어날지 예상하는 것이다.
- ”생각의 탄생” 중에서

이벤트와 엔터프라이즈 애플리케이션
대부분의 엔터프라이즈 애플리케이션은 외부로부터 가해지는 자극에 대해 특정한 작업을 수행하는 반응적인 시스템이다. 시스템은 자극의 유형 별로 미리 정의된 작업을 수행한 후 시스템의 상태를 변경하거나 외부에서 인식할 수 있는 결과를 반환한다. 이처럼 시스템에 전달되어 특정한 반응을 야기하는 중요한 사건을 ‘이벤트(Event)’라고 한다. 여기에서의 핵심은 외부에서 유입되는 자극인 이벤트를 중심으로 시스템과 사용자 간의 상호작용을 바라본다는 점이다.

시스템의 동적 행위를 요구사항 관점에서 기술하는 유스케이스(use-case) 역시 이벤트에 대한 반응이라는 관점에서 시스템의 행위를 기록하는 분석 기법이다.

Iva Jacobson은 유스케이스 안의 한 단계를 트랜잭션(transaction)을 표현하는 것으로 설명한다. 그는 복잡한 상호작용이 다음과 같은 4가지 부분으로 구성되어 있다고 인식했다.
1. 일차 액터(Primary Actor)가 시스템에 요청과 데이터를 보낸다.
2. 시스템은 요청과 데이터를 검증한다.
3. 시스템이 내부상태를 변경한다.
4. 시스템이 그 결과를 가지고 액터에게 응답한다.
- Alastair Cockburn, 유스케이스 바로 쓰기

시스템은 이벤트에 반응하고 그 결과로 내부 상태를 변경한다. 대부분의 애플리케이션은 최종 상태의 저장과 조회만을 허용하지만 때때로 최종 상태에 도달하게 된 원인과 과정을 추적해야 하는 경우도 있다. 대표적인 예가 소스 버전 관리 시스템이다. 소스 버전 관리 시스템은 소스 코드에 대한 모든 변경 이력을 저장하기 때문에 언제라도 과거의 소스 코드를 조회하거나 복구할 수 있다.

모든 변경 이력을 저장하는 소스 버전 관리 시스템과 동일한 메커니즘을 사용하면 특정 시점의 소스 코드 상태를 얻을 수 있는 것처럼 원하는 시점의 시스템 상태를 얻을 수 있다. 이를 위해서는 시스템의 최종 상태뿐만 아니라 시스템에 전달된 모든 이벤트의 정보와 각 이벤트의 처리 결과를 시스템에 저장해야 한다. 이처럼 시스템의 변경을 야기하는 모든 이벤트를 저장하고 이를 사용해서 시스템의 중간 단계 상태를 복구하기 위해 사용할 수 있는 패턴 집합을 EVENTS 패턴이라고 한다.

EVENTS 패턴을 이해하는 가장 쉬운 방법은 입출금 내역이 출력된 통장의 한 페이지를 머리 속에 떠올리는 것이다. 신규로 개설한 예금 계좌에서 한 달간 발생한 거래 내역이 <표 1>과 같다고 가정하자.

<표 1> 한달 간의 계좌 거래 내역

<표 1>을 살펴보면 한 달간 2번의 입금과 4번의 출금이 있었음을 알 수 있다. 우측 하단에 표시된 최종 잔액(5,200,000원)은 2번의 입금(+6,000,000원)과 4번의 출금(-1,400,000원)에 의한 금액 변동이 누적된 것이다. 즉, 계좌의 최종 잔액은 각각의 입출금 행위에 의한 변동폭(+금액 또는 –금액)을 모두 합한 것과 동일하다.

계좌 내역을 관리하는 시스템에서 입금과 출금은 계좌의 잔액을 변경시키는 중요한 외부 사건이다. 따라서 계좌 관리 시스템의 중요한 내부 상태인 잔액을 변경하는 개별적인 입출금 행위가 바로 ‘이벤트’가 된다. <표 1>에서 거래일자, 시간, 적요, 출금(원), 입금(원) 항목이 모여 하나의 이벤트를 구성하며 잔액(원)은 시스템의 최종 상태를 표현한다. 따라서 <표 1>은 2개의 입금 이벤트와 4개의 출금 이벤트가 발생했으며 6개의 이벤트를 처리한 결과 계좌 잔액이 5,200,000원이 되었음을 나타내고 있다.

일반적으로 애플리케이션에 저장하거나 애플리케이션으로부터 조회할 수 있는 대상은 시스템의 최종 상태뿐이다. 이에 비해 시스템의 상태 변경을 이벤트 관점에서 표현하는 EVENTS 패턴을 적용할 경우 시스템의 최종 상태뿐만 아니라 시스템의 상태 변경을 유발시킨 모든 이벤트를 저장하는 것이 가능하다. 따라서 상태에 대한 모든 변경을 일련의 이벤트의 흐름으로 표현할 수 있다. 이처럼 이벤트에 의해서만 애플리케이션의 상태가 변경되도록 제한하고 상태 변경을 유발한 모든 이벤트를 저장함으로써 시스템의 상태 변경을 일련의 이벤트의 흐름으로 표현하는 패턴을 EVENT SOURCING 패턴이라고 한다.

<표 1>의 예제에서 EVENT SOURCING 패턴을 적용하지 않은 애플리케이션의 경우에는 최종 잔액인 5,200,000원만을 저장하고 있다. 이와 달리 EVENT SOURCING 패턴을 적용한 애플리케이션은 최종 잔액과 함께 2번의 입금 이벤트(8월 1일에 발생한 +3,0000원과 8월 26일에 발생한 +3,0000원)와 4번의 출금 이벤트(8월 4일에 발생한 -500,000원, 8월 10일에 발생한 -100,000원, 8월 18일에 발생한 -300,000원, 8월 25일에 발생한 -500,000원)를 저장한다.

EVENT SOURCING 패턴의 적용 여부는 애플리케이션이 어떤 질문에 답을 줄 수 있는 지를 결정한다. EVENT SOURCING 패턴을 적용하지 않은 애플리케이션은 현재의 최종 잔액이 얼마인지에 대해서만 대답할 수 있다. EVENT SOURCING 패턴을 적용한 애플리케이션은 현재의 최종 잔액뿐만 아니라 과거의 특정 시점의 잔액까지도 대답할 수 있으며 어떤 과정을 거쳐 최종 잔액에 이르게 되었는지도 알려 줄 수 있다.

<표 1>을 다시 살펴 보면 ‘잔액(원)’ 항목은 굳이 시스템에 저장하지 않더라도 애플리케이션에 저장되어 있는 모든 이벤트를 다시 처리함으로써 얻을 수 있다는 사실을 알 수 있다. 즉, 최종 잔액인 5,200,000원은 시스템에 보관된 2개의 입금 이벤트와 4개의 출금 이벤트의 증감액을 모두 더함으로써 다시 계산할 수 있다.

이벤트를 보관하고 보관된 이벤트를 다시 처리함으로써 특정 시점의 애플리케이션 상태를 복원할 수 있다는 점은 EVENT SOURCING 패턴이 제공하는 가장 큰 장점이다. 앞의 예에서 2010년 8월 10일의 시스템 상태를 복구하고 싶다면 계좌가 개설된 2010년 8월 1일부터 2010년 8월 10일 사이에 발생한 3개의 이벤트를 다시 처리하기만 하면 된다. 소스 버전 관리 시스템을 통해 특정 시점의 소스 코드를 복원할 수 있는 것처럼 시스템의 상태를 초기화하고 보관된 이벤트를 순차적으로 다시 처리함으로써 특정 시점의 시스템 상태를 복원할 수 있다.

EVENT SOURCING 패턴의 핵심 아이디어는 시스템의 최종 상태뿐만 아니라 시스템의 상태 변경을 야기하는 모든 이벤트 정보를 보관함으로써 상태 변경의 과정과 원인을 추적할 수 있고 과거의 특정 상태를 복원할 수 있다는 것이다. 빛보다 빠른 물질이 존재하지 않는 아인슈타인의 세계와 달리 물리 법칙의 제약이 없는 비트의 세계에서는 자유롭게 과거로 시간 여행을 떠날 수 있다.

<표 1>을 통해 알 수 있는 것처럼 EVENT SOURCING 패턴을 적용하는 가장 대표적인 예는 회계(Accounting) 시스템이다. 회계 시스템의 목적은 돈의 흐름을 추적하는 것으로 이를 위해 재무적인 변동을 야기시킨 모든 원인을 기록하고 그에 따른 결과를 추적할 수 있어야 한다. 모든 재무적인 원인과 결과를 추적할 수 있어야 한다는 회계 시스템의 기본적인 요구사항은 자연스럽게 EVENT SOURCING 패턴과 연결된다. 재무적인 변동을 야기한 모든 이벤트를 시스템에 저장함으로써 모든 돈의 흐름을 세밀하고 정확하게 추적할 수 있기 때문이다. 이처럼 EVENT SOURCING 패턴을 기반으로 회계 시스템 도메인에 적용 가능하도록 특화된 패턴들의 집합을 ACCOUNTING 패턴이라고 한다.

ACCOUNTING 패턴의 관점에서 회계 시스템은 재무적인 ‘이벤트(Event)’에 대해 ‘회계 항목(Accounting Entry)’을 생성함으로써 내부의 상태를 변경시키는 반응적인 시스템이다. <표 1>에서 시스템의 상태를 변경시키는 외부의 중요한 사건은 계좌에 대한 입출금이다. 따라서 입출금 행위가 회계 시스템에 대한 이벤트가 된다. 입출금 이벤트가 통지되면 이벤트에 포함된 정보를 처리한 후 계좌에 대한 변경 사항을 포함하는 ‘회계 항목’을 생성한다.
<표 2>는 <표 1>의 계좌 변동 내역을 ACCOUNTING 패턴의 핵심 요소인 ‘이벤트’와 ‘회계 항목’의 관점에서 표현한 것이다.
 

<표 2> ACCOUNTING 패턴 관점에서의 계좌 거래 내역

<표 2>는 <표 1>에 비해 입금과 출금이라는 두 가지 행위에 의해 계좌의 잔액이 변경되었다는 사실을 좀 더 명시적으로 표현하고 있다. 입금액과 출금액을 이용해서 직접 잔액을 변경하는 <표 1>과 달리 ‘증감액’을 계산한 후 이를 이용해서 잔액을 변경한다는 것에 주목하자. ‘증감액’은 ‘타입’이 입금일 경우에는 잔액에 더할 증가액(+부호)이 되고, ‘타입’ 항목의 값이 출금일 경우에는 잔액에서 빼줄 감소액(-부호)이 된다. 즉, 입출금 ‘타입’과 ‘금액’ 정보를 이용해서 ‘증감액’을 계산한 후 이를 현재의 잔액에 반영함으로써 최종 잔액을 계산하고 있다.

이제 <표 2>를 ACCOUNTING 패턴의 관점에서 설명해 보자. 앞서 설명한 바와 같이 ACCOUNTING 패턴의 핵심은 재무적인 변경을 야기시키는 외부의 사건인 ‘이벤트(Event)’에 반응하여 시스템의 상태를 변경시킬 ‘회계 항목(Accounting Entry)’을 생성하는 것이다. <표 2>의 경우 잔액 변경을 유발시킨 입출금 행위를 표현하는 ‘타입’, ‘금액’, ‘적요’, ‘거래일자’의 4가지 항목이 ‘이벤트(Event)’를 구성하며, 입출금 이벤트의 계산 결과인 ‘증감액’이 ‘회계 항목(Accounting Entry)’이 된다. ‘잔액’은 시스템의 최종 상태를 표현하며 최종 잔액은 모든 이벤트의 처리 결과인 ‘회계 항목’을 더한 값과 동일하다.

<표 3> 이벤트(Event), 회계 항목(Accounting Entry), 최종상태로 표현된 계좌 거래 내역

ACCOUNTING 패턴은 EVENT SOURCING 패턴의 한 예이기 때문에 EVENT SOURCING 패턴이 가지는 모든 특징을 포함한다. 첫 째, EVENT SOURCING 패턴과 마찬가지로 ACCOUNTING 패턴 역시 시스템의 상태 변경을 야기한 모든 ‘이벤트’를 저장한다. <표 2>를 살펴 보면 계좌의 잔액을 변경시킨 모든 입출금 이벤트 정보가 보관되어 있음을 알 수 있다.

둘 째, 과거 특정 시점의 상태를 알고 싶을 경우 특정 시점까지 발생한 모든 이벤트를 동일한 순서로 재처리하여 시스템의 상태를 복구하는 것이 가능하다. <표 2>에서 2010년 10월 8일의 잔액 상태를 알고 싶을 경우 2010년 10월 8일까지 발생한 모든 입출금 이벤트를 재처리함으로써 해당 시점의 최종 잔액인 2,400,000원을 계산할 수 있다. 그러나 ACCOUNTING 패턴의 경우 이벤트뿐만 아니라 이벤트의 처리 결과인 ‘회계 항목’도 함께 저장 가능하기 때문에 이벤트를 재처리하지 않고 단순히 특정 시점까지의 ‘회계 항목’을 모두 더하는 것만으로도 간단하게 특정 상태를 복구할 수 있다. <표 2>에서 2010년 10월 8일의 잔액은 해당 일까지의 ‘증감액’을 모두 더한 금액과 동일하다(2,400,000 = (+3,000,000) + (-500,000) + (-100,000)).

셋 째, 특정 시점의 상태뿐만 아니라 어떤 과정을 거쳐 해당 상태에 이르게 되었는지도 파악할 수 있다. <표 2>에서 2010년 10월 8일의 잔액인 2,400,000원은 입금 3,000,000원, 출금 500,000원, 출금 100,000원이라는 3가지 행위에 의한 결과라는 사실을 알 수 있다.

요약하면 ACCOUNTING 패턴은 EVENT SOURCING 패턴의 한 예로 ‘이벤트(Event)’를 통해서만 시스템의 상태 변경이 가능하며, ‘이벤트(Event)’를 처리하여 얻어진 ‘회계 항목(Accounting Entry)’을 시스템에 저장함으로써 시스템의 상태를 변경할 수 있는 패턴의 집합이다. 
 

<그림 1> 이벤트(Event)를 통지 받아 회계 항목(Accounting Entry)을 생성하는 ACCOUNTING 패턴

덧글

  • 영회 2011/12/08 00:14 # 삭제

    휴가 다녀와서 연락할테니.. 준비하세요. :)
  • 이터너티 2011/12/08 12:18 #

    웅? 제가 준비할게 있나요?
    혹시... 쑈? ㅡ.ㅡ;;
※ 로그인 사용자만 덧글을 남길 수 있습니다.