코드리스 가급적 코드 없는 개발 블로그

그런데 추상화가 뭔가요

전에 다녔던 회사에 한 훌륭한 백엔드 개발자 분이 계셨습니다. 그 분은 ‘추상화’라는 단어를 자주 사용하셨습니다. 개발자가 ‘추상화’를 자주 얘기하는 것이 이상한 일은 아닙니다. 하지만 아무래도 일상에서 매일 얘기하는 단어도 아니긴 합니다. 그래서인지 이게 언젠가부터 웃음 포인트가 되었습니다. 사내에서 일종의 밈이 되어서 약어로 ‘ㅊㅅㅎ’로 쓰기도 하고 슬랙에 커스텀 이모지 ‘ㅊㅅㅎ’가 생겨나기도 했습니다. 이 개발자 분은 이후에 말을 하다 ‘추상화’라는 단어가 나오면 부끄러운지 급하게 다른 단어를 골랐습니다. 부끄러워 하시는 모습을 꽤 자주 볼 수 있었던 걸 보면 ‘추상화’는 개발자에게 꼭 필요한 단어인 것 같습니다. 다른 단어를 골라내는 게 매번 어려웠던 걸 보면 대체할 만한 말도 마땅치 않은 것 같습니다.

그런데 추상화가 뭔가요?

추상화는 무엇이고, 개발자들은 왜 그렇게 추상화를 좋아할까요? 그 백엔드 개발자 분에 대한 애정을 담아 그를 옹호하는(?) 글을 써봅니다.

이 글을 읽기 전에 추상화가 뭐냐는 질문을 받아 보신 적이 있으신가요? 저는 있습니다. 대학생 시절, 원하던 과목의 수강신청을 실패하고 아직 자리가 남아 있는 수업을 찾다가 제 전공도 아닌 서어서문학과에서 ‘스페인문학비평’이라는 강의를 수강했었습니다. 강의 도중 ‘탁월한 리얼리즘 작가는 자신의 경험 소재들을 추상화한다’라는 맥락의 설명이 나왔습니다. 교수님은 학생들에게 “추상화가 무슨 뜻이지?”라고 물으셨습니다. 저는 그 강의를 듣던 학생들 중에 정말로 ‘추상화’라는 말이 뭔지 아예 몰라서 사전을 찾아 봐야만 했던 학생은 없었다고 믿습니다. 하지만 저를 포함해 어떤 학생도 자신 있게 추상화는 이런 뜻입니다, 하고 나서질 못했습니다. 분명 모두가 알고 있는 단어인데, 막상 설명하려고 하면 쉽지가 않습니다.

교수님의 대답은 명쾌했습니다. “카테고리화야.” 저는 무릎을 탁 쳤습니다. 각각의 개성을 가진 구체적인 대상들이 있을 때, 이 대상들의 개별적 특성을 무시하고 공통점에만 주목하여 하나의 카테고리로 묶어버리는 것, 그것이 추상화의 의미였습니다.1

요는 공통점을 찾아서 하나의 카테고리로 묶어낸다, 이 과정에서 개별적 특징들은 주목하지 않는다라는 점입니다. 예로 우리는 무지개의 색을 일곱 가지로 추상화합니다. 빛의 스펙트럼은 연속적이므로 무지개에는 사실 무수히 많은 색이 들어 있습니다. 하지만 우리는 연두색, 라임색 같은 색들의 미묘한 차이를 무시하고 ‘초록색’으로 추상화합니다. 또 추상화 방법은 여러 가지일 수 있습니다. 우리에겐 무지개 색을 일곱 가지로 카테고리를 나누는 게 일반적이지만, 문화에 따라 다섯 가지도 여섯 가지도 될 수 있습니다. 보르헤스의 글에 나오는 독특한 동물 분류2처럼 어떤 공통점을 찾았느냐에 따라 아주 독특한 추상화를 할 수도 있습니다.

추상화를 가장 적극적으로 사용하는 분야는 어디일까요? 저는 수학을 전공했는데, 아마 수학만큼 추상을 많이 다루는 분야도 없지 않을까 생각해 봅니다. 수학은 극도로 추상적인 학문입니다. 오로지 추상만 다룬다고 말할 수도 있을 것 같습니다.

에디슨이 어릴 때 물방울 한 개에 물방울 한 개를 더해도 물방울 한 개라며 $1+1=1$일 수 있다고 말했다는 유명한 일화가 있습니다. 만약 누군가가 진지하게 $1+1=1$을 주장한다면 수학에선 어떻게 설명할까요?

$1+1=1$이 맞는지 아닌지를 따져 보기 위해선 $1$, $+$, $=$ 등의 기호가 갖는 의미부터 생각해 봐야 할 것입니다. 자연수를 정의하는 가장 유명한 방법(앞서 말한 것처럼 추상화 방법은 여러가지일 수 있으니까요)인 페아노 공리계를 기준으로 생각해 보겠습니다. 페아노 공리계에서 $1$은… 아무 뜻이 없습니다! 그저 ‘자연수 집합 N에는 1이라는 원소가 있다’라고 하고 넘어갑니다. 인간이 처음 $1$이라는 개념을 만들어 낼 때, 또는 아이가 처음 $1$이라는 개념을 익힐 때에는 어땠나요? 사과가 한 개인 경우, 강아지가 한 마리인 경우, 꽃이 한 송이인 경우 등 구체적인 대상들로부터 $1$이라는 개념을 뽑아내어 추상화했습니다. 하지만 추상화가 되고 난 $1$은 이제 더 이상 사과도, 강아지도, 꽃도 아닙니다. 그냥 그런 게 있다 하고 빈 껍데기만 남아 있을 뿐입니다.

페아노 공리계는 이렇게 이름 밖에 없는 $1$이라는 원소를 먼저 정한 뒤, 네 가지 특징을 만족시키는 함수3를 제시해서 자연수를 구성합니다. 이 함수는 우리가 자연수를 세어 나갈 때 꼭 필요한 개념인 ‘다음 수’를 추상화한 것입니다. 하지만 추상화 된 이상 이 함수에 더 이상 ‘다음 수’라는 의미가 들어 있지는 않습니다. 앞서 $1$이 그랬듯, 그냥 조건 네 가지를 만족하는 함수 껍데기일 뿐입니다.

마찬가지로 $+$, $=$도 추상적입니다. 어떤 집합에서 몇 가지 조건을 만족하는 함수를 만들 수 있으면 우리는 그것을 그 집합에서의 덧셈4이라 부를 수 있고, 몇 가지 조건을 만족하는 관계를 만들 수 있으면 그 관계를 ‘같다’5라고 말할 수 있습니다. 자연수 집합에서 조건에 맞춰 $+$와 $=$를 구성하고 나면 $1+1=2$(여기서 $2=f(1)$입니다.)가 됩니다. $f$와 $+1$이 같은 것이 되기 때문입니다. 어릴 때 ‘수학귀신’ 같은 책을 읽으셨다면 수학자들은 $1+1=2$를 증명하기 위해 종이 한 장을 쓴다는 얘길 들어보셨을 텐데 그 정체가 이런 것입니다. 정확히는 증명을 한다기 보다 자연수를 구성하고 $+$와 $=$을 정의하는 과정입니다.

즉 왜 $1+1=2$인가를 답할 것도 없이, 애초에 $1+1$인 게 2입니다. 만약 어떤 수에 $1$을 더했더니 결과가 $1$이 나왔다면, 그 수는 $1$이어서는 안 됩니다. 추상화를 하고 나면 논리의 방향이 뒤집힙니다.

그리고 그 때문에 추상화를 하고 나면 기존보다 폭 넓게 개념을 적용시키는 것이 가능합니다. 사과가 한 개, 강아지가 한 마리여서 $1$이라는 개념을 생각해 냈다면, 이제는 $1$을 갖고 적당한 아무 사물이나 $1$처럼 다룰 수 있습니다. 자연수 집합 내에서 덧셈을 정의하고 잘 써먹었다면, 이 덧셈을 추상화해서 자연수가 아니라 유리수, 실수, 복소수, 나아가서는 루빅스 큐브나 화투패에도 덧셈을 정의할 수 있습니다(당연히 추상화 과정에서 개별적 특징이 뭉개지기 때문에 자연수에서의 덧셈과는 달라지는 부분이 생길 수 있습니다.). 같다라는 개념도 잘 추상화하면 수가 아닌 다른 것들의 집합, 예를 들면 게임 캐릭터의 집합이나 포켓몬 스티커의 집합에도 적용이 가능합니다.

지금까지 살펴본 추상화의 특징들을 근거로 개발자들이 왜 추상화를 사랑하는지 살펴 보겠습니다.

추상화하면 몰라도 될 것, 혹은 몰라야 할 것을 모를 수 있습니다. 추상화 과정에서 개별적 특징들은 무시했기 때문입니다. 직접 회원가입을 해서 닉네임을 설정한 유저든, 소셜 로그인을 통해 외부에서 닉네임을 받아 온 유저든, 유저 닉네임을 알고자 하면 유저 닉네임을 곧바로 알 수 있는 게 합리적입니다. 만약 직접 가입한 유저와 소셜 로그인 한 유저를 동일하게 유저라고 추상화 하지 않는다면 유저 닉네임을 나타내려 할 때마다 직접 가입한 유저면 이 필드가 닉네임이고 소셜 로그인한 유저면 저 필드가 닉네임이다, 하면서 어리석은 코딩을 해야 합니다. 외부 API를 쓸 때도 비슷합니다. 모바일 앱에서 유저의 이동 속도를 알고자 해서 관련 API를 활용하기로 했다고 가정해 봅시다. ‘유저의 현재 이동 속도를 알려줘’ 한 마디로 유저의 이동 속도를 알 수 있으면 참 간단하겠죠? ‘우선 유저에게 내가 위치를 물어봐도 되는지 권한 확인을 좀 해주고, 범지구위치결정시스템을 활용해서 경도와 위도를 받아와. 5초 뒤에 한 번 더 경도와 위도를 받아 온 뒤, 피타고라스 정리를 활용해서 차이를 계산해줘. 속력=거리/시간이니까 참고하고. 지구 둘레는 얼마니까 그 값을 활용하면 정확히 m로 알 수 있을 거야.’ 해야 한다면, 끔찍합니다.

추상화 하고 나면 코드가 유연해집니다. 뜻은 사라지고 빈 껍데기만 남은 덕입니다. 예를 들어 오늘 철수가 청소 당번이어서 청소를 해야 합니다. 별 생각 없이 철수.청소() 라고 코딩하면 당장 작동은 하겠지만 나중에 여러 문제가 생깁니다. 민수가 청소 당번이 됐을 때 코드 자체를 민수.청소()라고 수정하면서 부작용이 생기지는 않는지 두려워 해야만 합니다. 하지만 청소 당번을 추상화 해서 청소당번.청소() 라고 썼다면, 청소당번 자리에 철수를 넣었다 민수를 넣었다 하며 보다 유연하게 대처할 수 있었을 것입니다. 앞선 방법에선 철수에서 민수로 당번이 바뀌려면 코드 자체를 수정해야 했지만, 이 방법에서는 철수와 민수를 바꾸는 행동이 이미 짜여진 프로그램 위에서 일어날 수도 있습니다. 마음에 드시나요? 그럼 이 방법은 어떨까요? 각각의 학생들에게 ‘당번’이라는 속성을 받게 해서 그때그때 행동을 시키는 겁니다 철수.당번.행동(), 민수.당번.행동()을 매일 동작시키되 오늘은 철수.당번 = 청소당번(), 내일은 민수.당번 = 청소당번()과 같은 형식이라면요?6 청소 당번 외도 다양한 당번에 대처해야 한다면 이 방법이 유리한 점이 많아 보입니다. 추상화에는 여러 가지 방법이 있을 수 있고, 그 중 변하지 않는 부분을 껍데기로 남기고 변하는 부분을 알맹이로 없애버리면, 코드는 변화에 유연하게 대처할 수 있게 됩니다.

같은 맥락에서 각종 툴을 사용하는 데 있어서도 유연해집니다. 예를 들어 특정 데이터베이스의 기능에 우리 코드가 의존하고 있다면 이 데이터베이스를 다른 데이터베이스로 교체하는 데는 어려움이 따릅니다. 하지만 한 단계 추상화하여, ‘읽고 쓰고 수정하고 삭제할 수 있으면 데이터베이스로 보는 걸로 하자’라고 둔다면, 이 네 가지 기능을 갖고 있는 무엇이든 데이터베이스로 볼 수 있습니다.7 앞서 1의 의미를 얘기할 때처럼, 이제 데이터베이스란 뭐가 됐든 ‘읽고 쓰고 수정하고 삭제할 수만 있으면’ 된 것입니다. 데이터베이스를 다른 것으로 교체하는 것은 물론이고, 임시로 만든 엑셀 파일도 데이터베이스처럼 사용할 수 있게 됩니다. 극단적으로는, 이름만 ‘읽다’, ‘쓰다’, ‘수정하다’, ‘삭제하다’로 맞춰서 전혀 다른 기능을 넣은 엉터리 데이터베이스를 만들 수도 있습니다…..만, 다른 개발자들을 위해 그런 짓은 하지 않는 게 좋겠습니다.

이렇듯 잘 추상화된 프로그램은 나중에 수정하기 편리하고, 각종 변화에 유연하게 대처할 수 있고, 복잡한 것을 간단하게 만들고, 나중에 들어갈 작업 시간을 미리 절약할 수 있게 합니다. 따라서 개발자가 추상화를 고민하느라 작업 시간이 늘어나고 있다면, 어쩌면 걱정할 일이 아니라 미래의 작업 시간을 반으로 줄이는 일일지도 모릅니다.


1 교수님만의 독특한 아이디어는 아닐 것이라 생각하고 후에 자료를 찾다 보니 아리스토텔레스가 <형이상학>에서 비슷한 이야기를 했다는 것을 알게 되었습니다. 하지만 제가 완전히 소화하지 못한 내용이기 때문에 본문에는 적지 않았습니다. 더 자세히 아시는 분이 설명을 해주실 수 있으면 좋겠습니다. 관심 있으신 분들은 <형이상학> 7권을 참고해 주세요.

2 이 백과사전에는 동물을 다음과 같이 분류했다. (a) 황제의 소유인 것, (b) 방부처리 된 것, (c) 길들여진 것, (d) 젖을 빠는 돼지, (e) 인어, (f) 상상의 것, (g) 야생의 개, (h) 현재의 분류에 포함된 것, (i) 광분한 것, (j) 셀 수 없는 것, (k) 세밀한 낙타털로 만든 붓으로 그린 것, (l) 기타, (m) 방금 항아리를 깬 것, (n) 멀리서 보면 파리처럼 보이는 것 - 호르헤 루이스 보르헤스, <존 윌킨스의 분석적 언어> 중.

3 $N$에 $1$이라는 원소가 있고 다음 네 가지를 만족하는 $f$가 있으면 $N$은 자연수 집합입니다.

  1. $N$의 임의의 원소 $n$에 대하여 $f(n)$도 $N$의 원소다.
  2. $f(x)=1$을 만족하는 $x$는 $N$에 존재하지 않는다.
  3. $f(m)=f(n)$이면 $m=n$이다.
  4. $N$의 부분집합 $S$가 $1∈S$이며, 임의의 $n∈S$에 대하여 $f(n)∈S$라면, $S=N$이다.

4 러프한 설명: ‘항등원’이 존재하고 ‘교환 법칙’, ‘결합 법칙’이 성립해야 합니다.

5 집합 X에서 다음을 만족하는 관계 ~ 를 동치 관계라고 합니다.

  1. 임의의 $x∈X$에 대하여, $x$~$x$
  2. 임의의 $x, y∈X$에 대하여, 만약 $x$~$y$라면, $y$~$x$
  3. 임의의 $x, y, z∈X$에 대하여, 만약 $x$~$y$이고 $y$~$z$라면 $x$~$z$

6 관심 있는 분은 ‘Strategy Pattern’이라는 키워드가 도움이 될 거예요.

7 이와 관련해서는 ‘만약 어떤 것이 오리처럼 생겼고, 오리처럼 헤엄치고, 오리처럼 꽥꽥거린다면 그건 아마도 오리다’라는 의미의 The Duck Test라는 것이 있습니다.