4가지 원칙, 어쩐지 낯설지가 않습니다
예호나탄 샤르빗의 『데이터 지향 프로그래밍』을 흥미롭게 읽었습니다. 이 책에서 저자는 소프트웨어 시스템의 복잡성을 줄이는 방법론으로서, 제목과 동명인 데이터 지향 프로그래밍(Data-Oriented Programming, DOP)이라는 개념을 주창하는데요, DOP의 원칙(principle) 4가지는 다음과 같습니다.
데이터와 그 데이터를 조작하는 행위 코드를 분리합니다. DOP는 프로그래밍 언어에 종속적이지 않기 때문에 객체지향 프로그래밍(OOP)이든 함수형 프로그래밍(FP)이든 적용 가능합니다. OOP에서는 데이터만 들어 있는 클래스와 메서드만 들어 있는 정적 클래스를 나누는 방식으로 구현할 수 있고, 반대로 FP라도 closure를 써서 상태 변수를 lexical scope 안에 숨긴다면 이 원칙을 위반하게 됩니다.
DOP에서는 엔티티를 표현하는 수단으로 -클래스가 아닌- 범용 자료구조를 사용합니다. 여기서 말하는 범용 자료구조는 맵(파이썬의 Dict)이나 배열(리스트) 같은 것입니다. 책을 구현한다면 Book이라는 클래스를 만들고, 멤버 변수로 isbn, title, authors를 추가하는 게 아닙니다. (파이썬 기준으로) 'isbn', 'title', 'authors'를 key로 갖는 Dict를 만듭니다. 그리고 멤버인 authors는 저자를 표현하는 Dict의 List가 됩니다. 쉽게 생각하면, 데이터를 그냥 json으로 표현한다고 봐도 될 것 같습니다.
DOP에서 데이터는 불변(immutable)입니다. 즉, 한 번 생성되고 나면 값을 바꿀 수 없고, 값을 변경하려면 새로 생성해야 합니다. 이런 불변성은 여러 장점이 있지만 단순하게 구현하면 너무 비효율적입니다. 상태가 바뀔 때마다 모든 데이터를 새로 만들어야 하니까요. 그래서 기존 데이터를 효율적으로 공유하면서 바뀐 부분만 교체할 수 있는 영속적 자료구조의 도움을 받아야 합니다. 2007년 클로저(Clojure)의 구현 이후로 다양한 언어에서 영속적 자료구조 라이브러리가 개발되었습니다. 자바스크립트라면 Immmutable.js가 있고, 파이썬에는 pyrsistent가 있습니다.
데이터를 범용 자료구조로 표현하게 되면, 값의 타입이나 스펙, 정합성 등을 정의하고 관리할 방법이 필요합니다. 예를 들어, 어떤 데이터에는 어떤 필드가 필수가 있어야 하는지, 어떤 필드의 값은 어떤 조건을 만족해야 하는지와 같은 규약이죠.
클래스를 쓰는 경우에는 그런 규칙이나 제약을 코드 자체에 표현할 수 있습니다. 가령, 나이는 음수가 될 수 없다면 Age라는 클래스 생성자에 해당 로직을 넣을 수 있고, 책에는 반드시 제목이 있어야 한다면 역시나 Book 클래스 코드에 표현할 수 있습니다.
하지만 DOP에서는 그런 방식 대신 JSON 스키마와 유효성 확인 라이브러리 같은 도구를 이용해 검증 작업을 처리합니다.
이 4가지의 원칙을 채택함으로써 얻는 이점과 비용은 책에서 친절히 설명하고 있습니다.
이 원칙에 따라 프로그램을 짜면, json을 입력으로 받아서 처리하고 그 결과로 json을 리턴하는 함수들의 파이프라인 형태가 되지 않을까 싶습니다. 그래서인지 제게는 DOP 방법론이 그렇게 낯설지 않았습니다. R의 tidyverse에서 dplyr로 코딩하는 방식과 유사하게 느껴졌거든요.
tidyverse 세계에서는 데이터프레임이 json의 자리를 차지합니다. 데이터프레임은 RDB의 테이블이라고 생각하면 됩니다.
데이터프레임 안에는 데이터만 들어 있습니다. (json과 달리, 중첩된 데이터는 표현할 수 없습니다만) 그리고 데이터를 처리하는 공통 함수로 filter, mutate, select, groupby, summarise 등이 있고, 이렇게 데이터와 코드는 분리됩니다. (원칙 1)
책 엔티티를 표현하는 방법은 isbn, title, authors 컬럼을 갖는 데이터프레임입니다. 별도의 클래스나 타입을 정의하지 않고, 데이터프레임의 컬럼만으로 표현합니다. (원칙 2)
데이터프레임을 수정하려면, 원본을 변경하는 것이 아니고 새로운 데이터프레임을 만들어서 리턴합니다. (원칙 3)
그렇다고 tidyverse가 DOP라고 말하는 것은 아닙니다. 이런 라이브러리는 OLAP(Online Analytical Processing)라고 해서, 데이터 전처리나 집계, 분석 용도의 작업에 적합합니다.
OLAP에 상대적인 개념으로 OLTP(Online Transaction Processing)가 있습니다. 쇼핑몰에서 상품을 구매하는 것과 같은 트랜잭션을 처리할 때는, 전체 데이터가 아니라 특정 항목(Row)의 상태값만 변경해야 합니다. 이런 경우에는 동시성과 일관성을 지키면서도 빠른 응답 속도가 중요하고, 일반적으로 tidyverse 같은 방식으로 구현하지 않습니다.
하지만, DOP는 이런 유스케이스에도 적용 가능한 방법론으로서 제안된 것입니다. 그동안 데이터 배치 처리나 분석을 하면서 tidyverse 스타일에 익숙하고 또 좋아하지만, 서비스용 시스템을 개발할 때는 적용할 생각을 하지 않았는데요. 이 책을 읽고 나니 사이드 프로젝트에서부터 DOP 스타일을 한 번 시도해 보고 싶어졌습니다.
예호나탄 샤르빗, 『데이터 지향 프로그래밍』, 박성철 옮김, 에이콘출판(2024)