본문 바로가기
개발

객체지향 방법론 고찰

by 최승환 2024. 2. 16.

회사 블로그에 게시 했던 글을 옮겨 왔습니다.

https://blog-bigpico.tistory.com/28



안녕하세요, 빅픽처인터렉티브에서 프론트엔드 개발자로 일하고 있는 최승환입니다. 😀

 

이번에 책 '객체지향의 사실과 오해 - 조영호'를 읽고 느낀 소감을 공유하고자 글을 작성하게 되었습니다. 내용이 지식 전달의 목적으로 작성되어 있지는 않지만, 다른 사람이 어떤 것을 배우고 느꼈던 과정을 읽는 것만으로도 많은 도움이 되었던 경험이 있어 이러한 소감문을 공유하게 되었습니다. 🙇‍♂️


시너지를 생각하라, 전체는 부분의 합보다 크다. - 스티븐 코비 (stephen R. Covey)

 

책의 첫 장은 위와 같은 문장으로 시작된다. 벌써 호기심을 자극하고 재밌는 내용이 펼쳐질 것만 같다.

 

객체지향 방법론을 처음 접하게 된 건, 대학교 2학년 때 본격적으로 컴퓨터공학 전공과목들을 수강하게 되면서부터였다.

객체지향 패러다임이 담긴 프로그래밍 언어들을 공부하면서, '객체로 세상에 있는 모든 것들을 프로그래밍 할 수 있다!'는 내 나름의 대단한 느낀 점이 있었다. 이것은 내게 굉장히 큰 영감을 주었고 아직도 되새길수록 가슴을 뛰게 하는 것이 있으며, 내게 개발자로서 대단한 동기를 불러일으키기도 한다. 또한 덕분에 아직도 개발자를 내 천직이라 생각한다.

 

요컨대 세상은 점차 발전해가며 우리가 살고 있는 현실 세상(오프라인)에서 나아가 전자로 이루어진 세상(온라인)으로 확장되어 가고 있으며, 프로그래밍이란 이러한 온라인 세상에서 무엇이든지 할 수 있고, 창조할 수 있는 대단한 행위이다! 라고 생각하고 있었다. 당시의 나는 개발자란 마치 창조주와 같은 존재로까지 생각했다. 실제로 이미 꽤 오래전부터 온라인과 오프라인의 경계가 옅어지는 초경계, 초연결 시대가 도래했으며 '메타버스'란 키워드가 새로운 패러다임으로 대두되고 있다.

 

객체지향 방법론으로 현실 세계에 있는 모든 것들을 코드로 투영할 수 있다는 내 생각은 꽤 확고했으며, 의심의 여지가 없었고, 내 개발 철학 근간에 해당하는 것이었다.

 

그러나, 책의 내용은 다음과 같이 시작한다.

객체지향이라고 불리는 새로운 세상의 문을 연 대부분의 사람들은 "객체지향이란 실세계를 직접적이고 직관적으로 모델링할 수 있는 패러다임" 이라는 설명과 마주하게 된다. 이런 식의 설명이 전달하고자 하는 핵심은 객체지향 프로그래밍이란 현실 속에 존재하는 사물을 최대한 유사하게 모방해 소프트웨어 내부로 옮겨오는 작업이기 때문에 그 결과물인 객체지향 소프트웨어는 실세계의 투영이며, 객체란 현실 세계에 존재하는 사물에 대한 추상화라는 것이다.
...
아쉽게도 실세계의 모방이라는 개념은 객체지향의 기반을 이루는 철학적인 개념을 설명하는 데는 적합하지만 유연하고 실용적인 관점에서 객체지향 분석, 설계를 설명하기에는 적합하지 않다.
...
객체지향의 목표는 실세계를 모방하는 것이 아니다. 오히려 새로운 세계를 창조하는 것이다.
...
"소프트웨어 시스템이 해결하려고 하는 실재는 잘해봐야 먼 친척밖에는 되지 않는다.[Meyer 2000]"는 말로 소프트웨어의 세계와 실세계 사이의 거리를 잘 표현하고 있다.

 

책을 펼치자마자 '객체지향은 실세계의 투영'이라는 내가 갖고 있던 생각과 차이가 있는 내용이 나왔으며, 책의 다음 장을 넘기지 못할 정도로 깊은 생각에 빠졌었다.

책에서는 '실세계의 모방'이라는 개념이 객체지향의 철학적인 개념을 설명하는 데는 적합하지만, 객체지향 방법론이 실세계의 것들을 프로그래밍으로 나타내는 것과는 조금 다른 개념임을 말하고 있었다.

 

우선 내가 객체지향 방법론을 이해하고 있던 개념들을 정리해 보았다. 객체지향이란 우리가 대상을 어떻게 보느냐에 대한 방법이다. 우리는 사물이나 추상적인 개념을 어떤 한 대상으로 인지하고 객체로 구분한다. 그리고 그 대상의 복잡한 특징들을 단순화하고 혹은 일반화하기도 하며 특정 그룹으로 '분류' 한다. 이것이 객체지향의 특징 중 하나인 '추상화'이고 인간의 자연스러운 인지 과정이기도 하다. 또는 어떤 그룹에 속한 대상들의 세세한 특징에 집중하고 그것을 부각하여 기존의 것들과 또 다른 객체로서 구분하기도 한다.

이렇게 객체지향이란 인간의 자연스러운 인지 과정을 통해 프로그래밍하는 기법이기에 우리의 사고방식이 그대로 녹아들 수 있는 방법이기도 하다. 즉, 인간인 우리가 대상을 어떻게 관찰하고 있고, 어떤 특징을 추출해내고 있느냐에 따라 그 표현할 수 있는 방법은 무궁무진하다고 할 수 있다.

 

다만, 위 책의 내용들을 읽었을 때 내가 갖고 있던 객체지향에 관한 생각과의 미묘한 뉘앙스 차이를 느낄 수 있었다. 다시금 위 내용들을 잘 해석해 보자면, 즉 내가 객체지향에 대해 갖고 있던 생각이 틀렸음이 아닌, 아직 객체지향의 본질적인 특징에 관한 다른 이면, 그 미묘한 뉘앙스의 차이를 느끼지 못했음을 뜻한다.

따라서 우선 현실 세계의 객체와 소프트웨어의 객체. 그것들의 차이를 조금 더 알아볼 필요가 있었다.

 

그렇다면 현실 세계의 객체와 전자로 이루어진 세상(소프트웨어)의 객체는 무엇이 다른가?

두 객체의 가장 큰 차이점은 말 그대로 살고 있는 세상 그 자체가 다르다고 할 수 있겠다. 우리는, 현실 세계의 객체는 3차원 공간에서 어떤 물리적인 과학 법칙에 영향을 받으며 현실 세계에서 살아가고 있다.

 

반면에 전자로 이루어진 세상의 객체는 '메모리'라는 공간에 살고 있으면서, 프로세스가 시분할적으로 CPU에게 리소스를 할당받은 순간, 바로 그 순간에만 활동하게 된다. 또한 그들은 '컨택스트(context)'라는 큰 줄기에 따라 활성화된 동안에만 생명력이 불어넣어지게 되며, 이 컨택스트를 다음에 어떤 객체에게 전달해줄지 또한 본인의 역할이라고 할 수 있다. 전자로 이루어진 세상의 객체들은 서로 간에 컨택스트를 주고받으며 소프트웨어 시스템을 구축해가는 유기적인 존재인 것이다.

 

객체란 무엇인가?

지금까지 계속 '객체지향 방법론'에 대해 고찰하고 있었는데, 그렇다면 '객체지향 방법론'이란 무엇인가? 문장 그대로, '객체', '지향' 방법론이란 무슨 뜻인가? 도대체 객체가 무엇이기에 객체를 지향한다는 것인가? 객체지향 방법론은 이름부터도 무슨 뜻인지 쉽게 와닿지 않는다.

 

어떤 난해한 것을 이해할 때 내가 선택하는 방법 중 하나는 그것의 본질을 파고드는 방법이다. 개념이나 이론 등을 공부할 때 그것의 깊은 본질을 파악하고 가지를 넓혀 가는 것은 좋은 방법이다. 우선 '객체지향 방법론'이란 단어를 분해해 '객체'가 무엇인지 알아야 할 필요가 있겠다.

 

'객체'라는 단어를 떠올렸을 때 어렴풋이 드는 느낌으론 어떤 '덩어리'가 생각난다. 이 덩어리가 어떤 모양이고 어떤 특징을 가지고 있는진 확실하지 않지만 어떤 흐릿한 덩어리가 떠오른다.

내 머릿속에선 이 '객체'라는 단어를 설명하기 위해 무던히 많은 방법을 찾고 있었을 것이다. 그러던 중 내 뇌는 '시각적인 심상'이라는 도구를 선택했고 객체를 하나의 시각적 이미지로서 덩어리의 형태로 표현했다.

이 일련의 과정들은 추상적인 개념을 어떠한 설명할 수 있는 수단을 활용해 이미지로 '형상화'한 것이다. 이 경우의 수단은 내면의 시각적인 심상이다.

 

이번엔 다른 예로 굉장히 템포가 빠르고 주로 고음역으로 되어 있는 곡의 느낌을 하나의 선으로 표현한다고 해보자. 이 선을 그렸을 때 선은 부드러운 곡선의 형태를 띠기보다는 굉장히 각지고 뾰족한 형태를 띠게 될 것이다. 이것 또한 곡을 듣고 해석한 주관을 하나의 선으로써 '형상화' 한 것이다.

 

이러한 형상화 기법은 어떤 개념이나 사물을 우리가 인식할 수 있는 수단으로 그 대상을 나타내어 우리의 감각으로 그 대상을 관찰할 수 있도록 하는 인식 기법(과정) 중 하나이다.

 

우리는 시각이 많이 발달되어 있어 추상적 개념들을 형상화 할 때 주로 시각적인 이미지를 많이 떠올리게 된다. 그러나 시각적인 이미지는 여러 형상화 도구 중 하나일 뿐이며, 특히나 문화 예술 분야에서는 감상하는 이에게 작품의 주제나 의미를 어떤 특정한 수단으로 전달하려 하므로 다양한 형상화 기법이 나타난다.

가령 무용수는 몸짓이나 춤으로 작품을 표현하고 동작이란 수단으로 주제와 의미를 형상화한다. 작곡가는 음계와 악기들의 조화를, 문학가는 언어란 수단을 활용하여 주제와 의미를 형상화한다.

 

무용가 마사 그레이엄은 다음과 같이 말했다.

"저는 소리 없이 연습하는 동안에도 마음으로는 음악을 듣고 있습니다." "침묵 속에서 음악을 들을 때, 저는 마음으로 들을 뿐만 아니라 몸으로도 느낍니다."

 

'형상화 이미지'는 시각적인 심상 뿐만 아니라 청각, 촉각, 후각, 미각, 육체로 느끼는 어떠한 오감까지 인간의 다양한 인지 감각을 통해서도 발현된다. 무용가 마사 그레이엄의 경우 청각적인 형상화 이미지로 마음 속으로 곡을 들었고, 이 마음으로 들은 곡이 신체의 근육으로까지 퍼져 가는, 쉽게 설명할 수 없는 이 감각으로도 곡을 형상화 했다고 할 수 있다.

 

다소 모호할 수 있겠지만, 형상화는 '나타냄'을 뜻한다. 직감적이거나 추상적인 무언가를 수단과 형태에 상관없이 어떤 형상으로 나타낼 수 있다면 그것이 바로 형상화이고 개념의 발현이다.

 

리처드 파인먼의 흥미로운 이야기도 있다.

"저는 답의 형태적 특징을 먼저 봅니다. 특징을 잡아낸다는 것은 그림 그리는 데 절대적으로 필요한 거죠."

 

그는 어떤 문제를 풀 때 먼저 머릿속으로 이미지를 다듬는 작업을 했다. 그리고 난 뒤 그 답을 이미지 형태에서 방정식 형태로 변환시켰다.

"저는 사고의 대부분을 그런 그림을 좀 더 구체적으로 만드는 작업으로 채우죠. 물론 맨 마지막에는 수학이 등장합니다. 수학은 머릿속의 그림을 사람들에게 전달하고 이해시키는 데 효과적인 도구이기 때문입니다."

 

형상화 기법은 우리 뇌에서 일어나는 굉장히 창조적인 활동이다. 발명가들은 머릿속으로 물체를 구상하고 그것이 동작하는 역동적인 모습과 여러 부품의 결합을 생각해낸다. 그리고 그 물체를 다시 여러 조각의 부품으로 분해해 이 부품을 이루는 요소들을 또다시 또 다른 객체로 만들어간다. 이 물체는 이미 발명가의 머릿속에서 존재하는 대상이며, 이 존재하는 대상을 발명가는 이리저리 관찰해가며 완성해 간다.

흥미로운 점은 형상화 기법은 인지의 첫 단계인 '관찰'이 가장 활발히 일어나는 영역이기도 하다는 것이다. 우리는 본 적 없는 것은 상상하지도 못하며, 상상하지 못한 것은 생각하지도 못한다.

다시 말해 우리는 관찰한 무언가를 개념화해야만 하나의 대상으로 인식하고 그것을 관찰하였다 인식하며, 우리가 머릿속으로 하는 상상이란 인식과 동격으로 이미 그것은 머릿속에 존재하는 하나의 개념화 된 대상이라는 것이다.

 

여기서 중요한 건 형상화 기법을 통해 어떤 개념들을 우리가 인식할 수 있는 하나의 구체적인 대상으로써 나타낼 수 있다는 것이다. 우리는 대상으로서 인지한 것은 하나의 실체로 인식할 수 있게 된다. 바로 이 우리의 감각으로써 만들어진 감각 속에 실존하는 대상을 '객체'라고 할 수 있겠다.

 

지금까지의 설명은 추상적인 개념들을 위주로 하였으므로 다소 뜬구름 잡는 얘기 같았을 수 있겠다. 쉽게 말해, 주위를 한번 둘러보라, 우리의 인지적 관점에서 경계를 지을 수 있는 모든 대상이 객체이다. 당장 이 글을 입력하고 있는 노트북과 키보드도 객체이고, 지금 앉아 있는 의자와 앞에 있는 책상도 객체이다. 창밖에 보이는 건물, 자동차 그 외 기타 등등 모든 것들이 전부 다 객체이다. (인식과 객관적 실재 사이에 철학적 의견이 있겠지만, 철학은 내가 그리 잘 아는 분야가 아니다.)

 

추상화

객체지향 방법론을 이야기할 때 빠지지 않고 등장하는 핵심 개념 중 하나가 바로 '추상화'이다. 앞서 객체지향 방법론은 인간의 인지 과정을 그대로 담아낼 수 있기에 강력한 개발 방법론이라 하였다.

우리가 관찰을 통해 대상을 인지하고 형상화 기법을 이용해 그 대상을 구체화, 실체화했다면, '추상화'는 그 대상을 나타내기 위해 대상의 어떤 특질을 관찰하고 집중했는가에 대한 개념이다.

 

내 앞에 펜이 하나 있다고 하자. 펜을 쥐고 펜촉을 꾹 누르면 잉크가 흘러나온다. 방금까지 내가 펜이라고 인식하던 대상은 펜과 잉크로 분리되었다. 이제 이 펜을 반으로 부러뜨려 보자. 펜이 부러지면서 쪼개진 수많은 플라스틱 조각들과 펜 뚜껑 등 수많은 물체로 분리되었다. 하지만 여전히 이것은 펜이라고 부를 수 있다.

우리는 어느 경계까지 그것을 하나의 대상으로 인식하는가? 미시적인 관점으로 펜을 구성하고 있는 펜의 원자 하나하나까지 펜이라고 지칭할 수 있는 것인가? 혹은 펜을 쥐고 있는 손 역시 펜에 압력을 가해 잉크가 흘러나오게 하는 글을 쓰는 수단에 해당하므로 손 역시 펜의 한 요소가 되는 것은 아닌가? 어디까지를 사물의 경계로 봐야 하는가?

물론 철학적인 관점에선 수많은 논의가 이뤄질 수 있겠으나, 일반적인 관념상으론 '펜을 쥐고 있는 손'이 '펜'이 될 수는 없다. (그러나 모든 것이 거시적 관점으론 하나의 우주라는 존재 일원론이 있다.) 이렇듯 우리가 현실 세계를 인지한다는 건, 관찰한 대상의 경계를 정의하고 그것의 형질을 파악해가는 과정이 포함된다.

 

우리 주변에 있는 모든 지칭할 수 있는 것들은 추상화의 결과이다.

우리는 종이나 화면상에 정해진 규칙에 따른 특정 기호로 우리가 이해할 수 있는 모양으로 된 것들을 '문자'라고 지칭하며, 이러한 문자들을 문법적 규칙에 따라 나열한 것들을 '문장'이라고 지칭한다. 문장의 나열로 내용을 담고 있는 것을 '글' 이라고 지칭하며, 글은 의사소통을 위한 '언어'가 된다. 또한 문자, 글뿐만 아니라 음성이나 몸짓, 또는 인간 이외의 다른 동물들의 의사소통 체계 역시 언어라 할 수 있다.

 

'종이나 화면상에 특정 기호로 이해할 수 있는 모양으로 된 것들을 '문자'라고 지칭하며...'

 

이것은 우리가 '정해진 규칙에 따른 특정 기호' 라는 특성에 초점을 맞춰 추상화를 통해 '문자'라는 개념을 탄생시킨 것이다. 어떤 도구로 쓰여져 있던 '정해진 규칙에 따른 특정 기호'란 특성을 만족하는 것들을 우리는 '문자'라고 인식한다. 이와 마찬가지로 '문장'과 '글' 역시 각각의 특성에 초점을 맞추어 '문장'과 '글'이라는 개념으로 탄생 시켰고, '문장'과 '글'이라는 개념이 가진 특성을 만족하는 것들을 '문장', '글' 이라고 인식한다.

추상화의 핵심은 우리가 관찰한 대상의 '어떤 본질에 집중 했는가'이다. 추상화는 세세한 디테일을 덜어내고, 그 본질을 추구하는 생각 도구이다. 추상화는 인간의 인식 체계에서 '개념'이라는 명사를 구축해가는 과정이다.

 

'개념'은 추상화를 통해 정제된 결과물이다. 추상화는 세상의 복잡한 것들을 그 본질로 말미암아 사고하게 되는 대단한 지적 행위이다.

 

추상화의 대가 피카소는 다음과 같이 말했다.

"당신들은 보고 있어도 보고 있지 않다. 그저 보지만 말고 생각하라. 표면적인 것 배후에 숨어 있는 놀라운 속성을 찾으라."

 

본질에 집중하면 부가적인 것들은 배제되고 그 핵심에 집중하게 되어 영감을 얻게 되기도 한다. 다음 사례는 어느 한 분야의 추상화 과정이 진행되어 그 개념이 과학, 미술, 산업 등 분야 간의 경계를 초월한 예시이다.

프랑스의 생리학자 마레는 사람이 움직일 때 뼈나 관절의 위치가 어떻게 변하는지 알고 싶어 했다. 그는 모델에게 전신을 덮는 옷을 입힌 다음, 그 옷 위에 사지의 주요한 뼈를 따라 하얀 선을 그었고 주요 관절부터 하얀 점을 크게 찍었다. 그 후, 마레는 모델이 검은 배경 앞에서 움직이는 연속 사진을 찍었다. 사진에 나타난 모습은 육체가 사라진 점과 선의 집합이었다. 추상이 된 것이다.

마레의 사진

화가이자 생리학자인 폴 리셰는 마레의 추상적인 사진이 사상 최초로 사람의 동작에 대한 정확한 물리적 역학분석을 가능하게 할 만큼 중요한 것임을 직감했다. 그는 마레의 사진을 분석해 몸에 가해지는 힘, 다양한 동작에서의 무게중심점 등을 계산해냈다.

 

폴 리셰의 계단을 내려오는 사람 스케치

20세기 초 당시 화가들은 움직임에 큰 관심을 갖고 있었다. '어떻게 하면 고정된 캔버스에 움직이는 대상을 효과적으로 묘사할 수 있을까?' 라는 것이 그들의 주된 물음이었다. 그런 점에서 마레의 작업이 그들에게 큰 영향을 끼쳤다. 뒤샹 역시 마레와 리셰의 영향을 받아 '움직임'을 추상화 해 '계단을 내려오는 누드'라는 작품을 탄생시켰다.

마르셀 뒤샹의 계단을 내려오는 누드 #2

뒤샹의 '계단을 내려오는 누드'가 더 대단한 점은 '움직임'을 추상화 함으로써 정적인 캔버스에 '시간'을 담아 냈다는 점이다. 뒤샹은 시간을 쪼개고 계단을 내려오는 사람의 형상을 여러 정지된 화면으로 늘어 놓았다. 이 작품에 역동성을 불어 놓는 건, 바로 이 연속적인 장면을 바라보는 관찰자의 눈이다.

정지된 화면을 늘어 놓아 역동적인 움직임을 만들어내는 기법은 영화 산업에도 많은 영향을 주었다. 사진술의 발달로 이러한 기법이 영화 산업계에 빠르게 흡수 되었고 그 결과로 동영상이 탄생하였다. 또한 마레가 그리 했던 것처럼, 배우들의 몸에 인식 센서를 부착한 모션 캡처 기술도 발달하였다. 배우들은 컴퓨터로 본인의 움직임을 녹화하고 스크린으로 탄생하는 본인의 형상을 통해 자기 자신을 추상화 했다고 볼 수 있다.

 

개념

개념은 우리의 인지 과정 중 가장 마지막에 있는 결과이다. 위 언급한 인지 과정을 거쳐 어떤 명사로 지칭되어지는 것을 '개념'이라 한다.

 

우리는 서로 같은 특성을 가진 것들을 동일한 대상으로 일반화하며 그것들을 하나의 '개념'으로 인식한다. 이렇게 하나의 개념 집합 속에 있는 것들을 그 개념 하에 '같다'고 표현할 수 있으며, '같다'고 표현할 수 있는 개념 집합을 가리키는 말을 '외연'이라 한다. 예를 들어, 언어라는 개념의 외연은 글, 음성, 바디랭귀지이며, 동물의 외연은 소, 말, 사자 등이다.

 

'외연'과 반대되는 논리적 개념으로 '내포'가 있다. 내포는 '개념'에 속한 대상들이 공통으로 지니는 성질의 전체를 뜻한다. 예를 들어 자동차라는 개념을 '운송 수단'과 '네 바퀴를 가지고 있는 것'이라는 특성을 내포하는 것으로 정의한다면, 바퀴가 세 개인 운송 수단은 자동차라는 개념 집합에 속하지 못하게 된다.

다른 예를 들어 옷이라는 개념을 '붉은색으로 된'이라는 특성을 내포하고 있다고 정의한다면, 붉은 색 이외의 옷들은 옷이란 개념 집합에 속하지 못하게 된다. 즉, 내포는 우리가 그 개념의 특성을 어떻게 정의하고 있는지를 뜻한다.

'외연'과 '내포'는 서로 반대되는 개념이며, 한 쪽의 범위가 넓어지면 필연적으로 다른 한 쪽의 범위는 좁아진다.

 

'외연'과 '내포'의 논리적 개념은 소프트웨어를 만들어 갈 때 모듈의 크기(관심사 및 책임의 크기)를 정하는 문제와 연관된다. 눈으로 보이는 예시를 들기 위하여 웹 어플리케이션의 화면을 만드는 Frontend 작업을 한다고 하였을 때, 이는 각 컴포넌트의 수준을 어느 정도로 나누게 되는지에 해당한다.

 

CardList 컴포넌트 분리

다음은 CardList 컴포넌트를 화면상에 보이는 유의미한 단위 수준으로 분리한 것이다. CardList라는 외연에는 다음과 같이 CardItem, Image, Text, Avatar, Date 컴포넌트가 속한다. 또는 화면에 나타나지 않지만, 내부에서 동작하는 시간 계산 모듈, Image 로드 모듈 등 각 모듈별로 관심사 분리를 하여 구분할 수도 있다.

 

컴포넌트를 더 Atomic 하게 나눌수록 재사용성이 높아지고 프로젝트 내부의 통일성이 높아진다. 또한 CardItem내부에 부품을 끼워 넣듯이 다른 컴포넌트를 삽입하여 커스터마이징 하기 쉬워진다.

또는 서버에서 내려주는 NewsCard 데이터가 일정하게 규격화 되어 있다면, CardList에 들어가는 CardItem 컴포넌트를 CardItemType1, Type2... 등 다른 UI 타입으로 변환해 주는 것도 가능하다. 데이터를 mapping 해주는 것은 CardList가 Container 역할을 할 수도 있고, 혹은 추상화 된 mapping 모듈로 처리할 수도 있다.

다만 가장 중요한건 Fontend와 Backend의 NewsCard 데이터 '개념'의 통일이다.

 

소프트웨어를 설계함에 있어 '개념' 즉, '객체'를 어떻게 설계할 지는 쉬운 일이 아니다. 오늘날의 소프트웨어는 그 복잡성이 높아 모듈이라 불리우는 객체로 각 기능을 분리하고 그것들의 유기적인 결합으로 소프트웨어를 설계해간다. 질 좋은 소프트웨어를 만드는 것은 이러한 객체들을 잘 설계하는 것이라 할 수 있다.

 

소프트웨어 공학을 공부하며 좋은 객체 구조를 설계하기 위해 UML로 시스템 구조도를 그렸던 경험이 있다. 기록을 위한 데이터베이스를 설계하는 경우엔 이러한 엔티티의 구조에 초점을 맞춰 설계하는 게 좋은 방법일 수 있겠으나, 소프트웨어의 객체는 정적인 무언가가 아니다. 다시한번 짚고 가자면, 전자 세상을 살아가는 객체는 그들 스스로가 컨택스트를 관장하며 대단히 역동적이고 책임감 있는 존재들이다.

 

객체의 역할과 책임, 협력

소프트웨어는 목적을 수행하기 위한 체계적인 시스템이다. 소프트웨어는 사용자에게 기능을 제공하고 사용자의 요구를 달성한다. 소프트웨어 세상에서 존재하는 객체는 이 명백한 목적을 달성하기 위해 협력 관계를 구축하며, 각자의 역할에서 그 책임을 다한다.

 

이렇게 객체 간의 협력 관계를 구축한다는 점은 실세계의 객체와 유사하다. 우리 역시 타인의 도움 없이는 그 도움이 어떤 형태이든 다른 사람과 협력 관계를 유지하지 않고는 살아가지 못한다. 단순히 매장에서 서비스를 받는 행위 역시 우리가 주변에서 쉽게 접하는 다른 사람들과의 협력 관계이며 직장에서 다른 사람과 함께 일하는 행위, 혹은 우리 스스로 어떤 도구를 사용하는 것 역시 다른 객체와의 협력이라 할 수 있겠다. 바로 이런 '객체 간의 협력'이라는 유사점이 객체지향 방법론이 '실세계의 투영'이란 개념을 기반으로 한다는 점이다.

 

커피 매장에서 음료를 주문하는 과정으로 예를 들어보겠다. 고객은 메뉴판으로 판매하는 음료 목록을 확인한 후, 캐시어에게 음료를 주문한다. 주문을 받은 캐시어는 해당 주문 내역을 바리스타에게 전달한다. 바리스타는 음료를 만든 후, 음료 제조가 완료 되었음을 캐시어에게 알린다. 캐시어는 고객에게 음료를 전달한다.

 

위와 같이 우리 주변에서 쉽게 볼 수 있는 커피 매장의 예시에서도 객체 간의 협력 관계가 잘 나타난다. 커피 매장의 객체들 역시 '음료 제공'이라는 그들의 목표를 이루기 위해 협력하므로(물론 객체는 각 객체의 목표 달성에만 관심이 있을 뿐, 시스템의 궁극적인 목표 달성엔 관심이 없다.) 하나의 '협력 시스템'이라 할 수 있겠다. 이러한 협력 시스템에는 각 객체가 목표 달성을 위해 맡게 되는 '역할'이 있다. 여기서의 역할은 '고객', '캐시어', '바리스타'이다.

 

객체는 다른 역할을 지닌 객체의 협력을 이끌어내기 위해 요청을 보낸다. 위 예시에선 '고객'은 메뉴판에 적힌 메뉴의 품목을 '캐시어'에게 말로 전달한다. 이 요청은 고객과 캐시어 둘 다 이해할 수 있는 서로 약속된 형태의 요청이다. 객체지향에선 이 요청을 '메세지'라고 한다.

캐시어의 역할을 담당하는 객체는 고객 객체에게 주문 메세지를 받았을 때 캐시어로서 이를 처리해야 할 '책임'이 있다. 객체지향에선 어떤 역할이 협력을 위해 요청을 처리해주어야 하거나 동작을 수행해야 하는 것들을 '책임'이라고 한다. 각 역할들은 협력 시스템에서 자신들의 의무와 책임이 있다고 할 수 있다.

 

이렇게 객체가 협력 시스템에서 역할이 담당해야 할 책임을 수행할 수 있다면, 객체가 그 역할을 담당할 수 있음을 뜻한다. 이것은 그 객체가 갖고 있는 특질이다. 객체가 그 역할과 관련된 특질을 내포하고 있다면 그 객체의 역할 즉, 협력 시스템에서 객체의 외연이 결정된다.

 

또 다른 재밌는 점은, 이렇게 객체들은 협력 관계에서 그들이 마땅히 담당해야 할 '책임'만이 있다. 더 풀어서 설명하자면, 객체는 메세지를 요청 송신자가 이해할 수 있는, 서로 약속된 형태로만 처리할 수 있다면 이 요청을 '어떻게' 처리할 지에 대해선 온전히 그들의 몫이라는 것이다.

 

우리가 마우스라는 객체를 동작하는 것을 예시로 들어보자. 우리는 마우스를 클릭하면 컴퓨터에서 버튼 눌림이 처리된다는 것만을 인식하고 마우스를 다룬다. 우리가 마우스를 클릭 했을 때, 그 내부에서 동작하는 어떤 복잡한 전자기적인 처리 과정은 생각할 필요도 없다. 우리는 단순히 클릭과 움직임만으로 마우스에게 요청을 보낸다.

이렇게 요청을 보내는 객체가 다른 객체의 내부적인 동작을 전부 알 필요가 없음은 협력 시스템에서 구조가 갖는 복잡성을 굉장히 낮춰 준다. 이것이 객체지향의 장점이며, 이것을 객체지향에서는 '캡슐화', '은닉화' 라고 한다.

캡슐화, 은닉화를 통해 객체는 그들의 독립성과 자율성이 보전되며, 특정 모듈의 수정이나 업데이트가 필요할 때, 이 과정이 전체 시스템에 영향을 받지 않게 된다.

 

앞서 객체가 '책임'을 수행할 수 있다면 그 역할을 담당할 수 있다고 하였다. 그 말인 즉슨, '캐시어'에게 전달 받은 '음료를 제조하라' 라는 메세지를 처리할 수만 있다면 어떤 객체도 커피 매장이라는 협력 시스템에선 '바리스타' 역할을 수행할 수 있음을 뜻한다.

 

음료를 제조할 수 있는 객체들은 '바리스타' 역할을 수행할 수 있으며 그들은 그들만의 방식으로 음료를 제조할 것이다. 이 행위엔 그들의 노하우와 기술이 담겨 있다. 바리스타 객체들은 그들이 내포하고 있는 특질에 따라 다르게 동작하게 된다. (물론 응답은 요청 송신자가 이해할 수 있는 형태이다.) 이것을 객체지향에선 '다형성'이라고 한다. 동일한 메세지를 객체의 특질에 따라 다른 방식으로 처리하며 협력 체계를 유연하게 확장할 수 있는 객체지향의 특징 중 하나이다.

 

객체는 협력 시스템에서 협력적인 존재이기도 하지만 또한 그들의 역할을 스스로 책임지는 독립적이고 자율적인 존재이기도 하다. 각각의 '바리스타'들은 그들만의 제조 방식으로 음료를 제조할 수 있다. 즉 음료 매장이라는 협력 시스템에선 각 바리스타의 제조 스킬이 음료 매장의 품질을 좌우한다. 이는 소프트웨어에서도 마찬가지로 각 모듈의 성능이 어떠한지에 따라 소프트웨어의 품질을 결정한다고 할 수 있다.

 

이번엔 바리스타 객체에게 '음료를 제조하라' 라는 메세지가 아닌, 좀 더 상세한 작업 지시가 담긴 요청을 보낼 수도 있다. 예를 들어 바리스타 객체에게 '설탕 3스푼을 넣어' + '음료를 제조하라' 라는 메세지를 보낸 경우를 상정해보자 (비즈니스를 분석한 모종의 이유로 설탕을 넣게 되었다고 하자)

이제 바리스타들은 항상 음료를 제조할 때 설탕 3스푼을 넣게 될 것이다. 현재까지는 이러한 경영 방침으로 잘 운영되왔다고 하자. 하지만, 상권의 변화가 생겨 쓴맛을 좋아하는 잠재 고객들이 많아진 경우, 이 고객들이 매장을 방문했을 때에도 바리스타들은 음료를 만들 때 설탕 3스푼을 넣게 될 것이고 이는 고객 만족이라는 커피 매장의 궁극적인 목표를 달성하는 데 위배되게 된다.

또한 현재 캐시어는 바리스타들이 항상 '설탕 3스푼'을 넣을 것이라는 것에 대해 '알고 있는' 상황이다. 앞으로 쓴맛을 좋아하는 고객도 만족 시키기 위해 '설탕 3스푼을 넣어라' 라는 요청을 제거하고 싶은 경우, 캐시어와 바리스타 양쪽의 업무 모두 수정해야 하는 비용이 발생하게 된다.

 

이렇게 객체에게 지나치게 상세한 요청을 보내게 되면 그들의 자율성이 저하되며 협력 시스템에도 불필요한 결합도를 가중시키기게 된다. 객체지향의 장점은 자율적인 객체들의 협력에서 나온다. 객체에게 지나친 책임을 가중시키는 것은 협력을 주고받는 객체들 간에 몰라도 되는 정보들을 알아야 되는 경우마저 생길 수 있으며, 이는 캡슐화 원칙에도 어긋나게 된다. 또한 서로 요청을 주고받는 객체 중 한 객체의 변화가 다른 객체에까지 쉽게 영향을 미치게 되며 시스템에 원하지 않는 사이드 이팩트가 발생할 수도 있게 된다.

 

메세지는 협력 시스템의 상세 설명서와 같다. 이 메세지를 통해 협력 시스템에서 객체들이 어떠한 행동을 하고 어떠한 요청을 주고 받는지를 파악할 수 있다. 메세지는 협력의 집약이라 할 수 있으며 이 메세지로 협력 시스템이 구성되게 된다.

이와 같은 메세지를 중심으로 객체지향 시스템을 설계하는 '책임 주도 설계' 기법이 있다. '책임 주도 설계' 기법은 객체의 정적인 데이터에 초점을 맞추어 시스템 구조를 설계하는 것이 아닌, 객체들의 행동과 그들이 주고받는 메세지(협력과 책임)에 초점을 맞추어 구조를 설계하는 방식이다.

객체지향 시스템을 설계하는 것은 객체들이 유기적으로 협력해서 살아가는 세계를 창조하는 것과 같다. 단순히 객체의 정적인 데이터에 집중해서 설계하게 되면 시스템 컨택스트를 무시한 채 그 구조를 설계하게 되고 객체의 근본적인 존재 이유인 '다른 객체와의 협력'을 무시한 채 구조를 설계하게 된다. '책임 주도 설계' 기법은 이 단점을 보완하기 위해 고안되었다.

 

'책임 주도 설계' 기법에서는 객체가 가진 속성으로 객체의 행위를 결정하지 않고 행위를 먼저 식별한 후, 행위를 수행할 수 있는 적절한 객체를 찾아가며 구조를 설계한다.

우선 소프트웨어가 제공하는 기능을 소프트웨어의 책임으로 정의한다. 그 후, 이 소프트웨어의 책임을 수행할 수 있는 적절한 객체를 찾아 시스템의 책임을 할당한 후, 이 할당된 책임을 수행하기 위해 다른 객체의 도움이 필요한지를 파악한다. 도움이 필요하다고 판단되면 다른 객체와 협력하기 위해 '어떠한 메세지가 필요한지'를 파악한다. 이 메세지들을 파악한 후, 메세지를 수신하기에 적합한 객체를 설계한다. 메세지를 수신받는 객체는 이 메세지를 처리할 '책임'이 있다.

결과적으로 메세지를 통해 협력이라는 관점에서 시스템의 커다란 책임을 분배해 가는 것이다. 다시 이 책임을 분배 받은 객체가 다른 객체의 도움이 필요하다면 위 과정을 반복해가며 구조를 설계한다.

 

'책임 주도 설계' 기법의 핵심은 객체의 행위를 객체 자체의 정적인 속성이 아닌 다른 객체와 유기적인 협력 관점에서 정의한다는 것이다. 이것은 객체를 고립된 상태로 놓고 시스템을 설계하는 것과는 근본적으로 다른 방법이다. 협력 시스템에서 객체의 책임을 결정하는 것은 메세지이다.

이렇게 객체가 수행할 수 있는 메세지를 중점으로 설계하는 방법은 객체의 인터페이스를 정의하기 쉽게 해 준다. 객체는 외부에 공개된 상호작용을 위한 접점(인터페이스)과 그들 내부의 구현으로 구성된다. 인터페이스를 쉽게 정의할 수 있음은 위에 예시로 들었던 마우스의 클릭의 경우와 동일하다. 송신자는 단순히 객체에게 어떤 요청을 보내면 어떤 결과를 받을 수 있음만 인지하면 되며, 요청을 수신하는 객체의 캡슐화된 내부 로직에 영향을 받지 않게 된다. 또한 이는 객체의 자율성을 보장하는 것이기도 하다.

인터페이스만 동일하다고 하면, 다른 어떤 객체와도 상호작용 할 수 있게 된다. 프로그래밍 하며 다른 라이브러리나 다른 시스템의 기능을 사용하는 경우 그것들이 제공하는 API만 알면 그것들의 내부 수정이나 버전업과는 상관없이 기능을 사용할 수 있으며, 웹 개발팀의 Frontend-Backend 조직 구조 역시 이러한 API의 명세로 분리할 수 있게 되었다.

인터페이스가 동일하다는 특성은 외연 집합에 속한 객체들과 동일한 방식으로 상호작용 할 수 있음을 나타낸다. 우리가 어떤 도구를 사용하던, 혹은 자동차를 운전하던 그것의 사용법만 알고 있다면 그 외연 집합에 속한 다른 것들과도 이전과 동일한 방법으로 상호작용 할 수 있게 된다.

 

정리

사실 객체지향은 프로그래밍에서만 나타나는 개념이 아니다. 우리가 살고 있는 세상, 어떤 조직간의 협업, 사물과의 작용, 나아가 추상적인 감정의 교류 등 우리가 객체로 인지하는 것. 세상에 존재하는 모든 것의 저변에서 나타나는 개념이라 할 수 있다. 단지 프로그래밍은 인간이 사고하는 논리적인 과정을 코드로 표현하는 것이므로 이러한 객체지향 패러다임을 대입하기가 더 쉬운 것이다.

아직도 공부하면 할수록 깨닫는 것이 더 많은 객체지향 방법론을 계속 공부하는 이유는 이러한 우리 세상 저변에 깔린 개념을 더 깊게 이해하고 싶은 마음 때문이기도 하다.

 

이러한 원론적인 이론들을 공부하면 할수록 모든 본질적인 개념들은 연결되어 있다는 것을 느끼게 될 때가 참 많다. 마침 이 내용들을 정리하면서도 고등학생 때 선생님께 졸업 선물로 받은 '생각의 탄생'이라는 책이 많은 도움이 되었다.

 

프로그래밍에서의 객체지향은 협력에 초점을 맞춰 객체를 어떻게 정의하는 가가 핵심이다. 하지만 다시 이렇게 반문 할 수도 있다. "객체는 무엇을 위해 협력하는가?"

소프트웨어의 객체는 소프트웨어가 제공하는 기능을 수행하기 위한 목표로 서로 협력한다. 다만, 소프트웨어의 기능은 비즈니스 관점에 따라 항상 수정되고 변하기 마련이다. 이렇게 변화하는 기반에서 협력 시스템을 구성해 봤자 기능의 변경이 있을 경우 그 기틀을 변경해야 할 만큼 큰 수정 작업이 필요하게 될 수도 있다.

이를 해소하기 위해 도메인 관점에서 소프트웨어를 설계하는 방법 또한 있다. 이와 관련된 서적은 기회가 된다면 꼭 읽고 이 문서처럼 정리하고 싶다.

 

객체지향 방법론에는 인간의 인지 과정이 그대로 담겨 있다. 그래서 더욱 흥미로운 것 같다.

마지막으로 객체지향 방법론을 내 나름의 기준에서 한 문장으로 정의하자면 '객체지향 방법론은 관찰의 방법론'이다.