OOP: revisited #1

프로그래밍이란 무엇일까? 이 질문에 답하는 것은 당황스러운 일이지만, 답은 매우 간단하다.

소프트웨어를 작성하는 것.

그렇다면, 소프트웨어를 작성하는 것은 무엇을 의미하는 것일까? 이 질문에 답하는 것은 어려운 일이지만, 내가 내린 답은 다음과 같다.

실세계에 존재하는 시스템을 모방하여 이를 컴퓨터 시스템위에서 구동시키는 일련의 과정

다시 한번! 그렇다면, 소프트웨어란 무엇일까?

소프트웨어는 당연히 하드웨어의 작동방식일테지만, 소프트웨어를 어떤 식으로 해부하느냐 혹은 바라보느냐(즉, 어떻게 모방하느냐)에 따라 그 패러다임은 심하게 달라질 수 있다. 그리고, 그 패러다임은 소프트웨어의 설계 및 구현은 설계에서 유지보수까지 소프트웨어 생명주기에 막대한 영향을 미치곤 한다.

패러다임을 이해하기 위해 그림 명화 두장을 준비했다. 왠 뜬금없는 미술이야기냐 라고 불평하실 분도 계시겠지만, 모방mimesis을 가장 극명하게 표현해내는 예술이 미술이므로 가져온 것이다. 일단 그림을 보면서 이야기해보자.

Las Meninas by Velazquez
Las Meninas by Velazquez

왼쪽의 그림은 디에고 벨라스케스Diego Rodríguez의 “시녀들”이라는 작품이다. 이 그림에 대한 자세한 내용은 위키백과를 통해서 확인하실수 있다.

1656년에 완성된 작품으로, 이 시기의 미술화풍을 잘 반영이라도 하듯 섬세한 표현이 두드러진다. 이 작품 내부에는 해석할만한 텍스트가 넘쳐나는 재미있는 작품이지만, 우리가 지금 이 작품에서 읽어야 할 것은 “텍스트”가 아니라 화풍이므로 자세한 것은 잊고 넘어가자.

Las Meninas - Picasso
Las Meninas - Picasso

오른쪽의 작품은 파블로 피카소 Pablo Picasso의 “시녀들”이다. 1957년에 그린 연작중 하나를 가져왔다. 흥미로운 점은 위의 “시녀들”을 파블로 피카소가 재해석해서 그린 그림이라는 점이다. 벨라스케스의 그림과는 엄청난 차이를 보인다. 이 차이는 어디에서 오는 것일까?

비록 벨라스케스의 시녀들을 보고 그린 그림이지만, 같은 이미지를 두고 두 사람의 해석이 다르다는 점을 알 수 있다. 사실, 같은 물건을 보고 그린 두 화가의 그림(사조도 다른!)을 비교하는 것이 가장 좋겠지만, 이 두 그림을 가지고도 충분히 모방에 있어서 사람의 생각 혹은 패러다임이 얼마나 작용하는지를 보여주는 사례라고 볼 수 있다.

그리고, 미술에서 나타나는 이 차이는 소프트웨어의 세계에도 그대로 적용된다.

미술의 사조가 화가가 받아들인 이미지를 어떤 식으로 그려내는가에 중점이 있다면, 프로그래밍의 패러다임은 프로그래머가 소프트웨어를 구성하는 기본 단위와 그 구성방식을 무엇으로 생각하느냐에 중점이 있다고 할 수 있다. 미술에 인상파, 고전주의, 낭만주의, 사실주의, 입체파, 추상파, 다다이즘등의 수많은 사조가 있다면, 프로그래밍에는 순차적 프로그래밍Procedual Programming, 객체지향 프로그래밍Object-Oriented Programming, 함수 프로그래밍Functional Programming, 관점지향 프로그래밍Aspect-Oriented Programming등이 존재한다.

순차적 프로그래밍은 소프트웨어를 일종의 시방서로 보는 패러다임으로 인간에 대한 배려보다는 컴퓨터라는 하드웨어를 어떻게 작동시킬 것인가에 초점을 맞추고 있다. (일반적인) C언어가 대표적인 사례라고 할 수 있으며, 대부분의 OS커널에서 제공하는 시스템 콜들이 이 패러다임을 따르고 있다. OS커널에서 제공하는 시스템 콜들을 기준으로 생각해본다면, 시스템 전체를 어찌 구성할 것인가 보다는, 하드웨어/커널이 가진 기능의 리스트에 가깝다. 또한, 하드웨어가 할 수 있는 일들을 목록으로 작성하고, 그 목록에 있는 일들을 어떤 순서로 실행할 것인가에 초점을 맞추고 있다.

함수 프로그래밍은 (수학적인) 함수들의 연결관계로 소프트웨어를 작성하는 방법론이다. 굉장히 유연하고, 직관적인 프로그래밍 방식이지만 인간이 기본적으로 세상을 인식하는 방식과는 차이가 있으며, 특수한 분야에서만 주로 사용되는 결과를 낳았다. 개인적으로는 상당히 관심이 가는 분야이며, 함수 프로그래밍분야에서 등장한 functor(함수자)의 개념은 C++에 도입되어 tr1::function과 같은 템플릿을 낳기도 하였으며, LISP나 scheme등의 언어적 기능들은 다른 객체지향 언어에 지대한 영향을 주었다.

마지막으로 오늘의 주제인 객체지향 프로그래밍이 있다. 객체지향 프로그래밍은 소프트웨어를 상태와 행동으로 정의되는 객체들의 상호연동을 이용해 소프트웨어를 표현한다. 객체지향 프로그래밍이 널리 사용되는 이유는 다름이 아니라, 객체지향 프로그래밍 패러다임이 제공하는 생각의 방식이 인간의 기본적인 사고방식과 유사하기 때문이다. 그리고, 그 유사성의 핵심은 추상화abstraction에 있다.

철학의 주제 중 하나인 인식론에서 그 유래를 찾아볼 수 있는 추상화는 다음과 같이 정리할 수 있다.

  1. 세상의 모든 사물은 다르다. 서로 같은 것은 존재하지 않는다.
  2. 그럼에도 인간은 사물을 구분짓는다. (Classification)
  3. 즉, 인간은 각 사물이 존재하는 공통된 성분을 추출하여 이를 토대로 세상을 인식한다.

이렇게 정리해놓으면 알쏭달쏭하지만, 쉽게보면 다음과 같다.

네모 두개

위의 그림을 놓고 “저 둘은 뭐죠?” 라는 질문을 던진다면, 보통 “네모 두개” 혹은 “직사각형 두개”라는 답변이 나올 것이다. 크기도 다르고 색깔도 다르지만, 자연스럽게 두 도형의 공통된 특징을 추출하여 개념화하는 것이다. 이 과정이 인식론적 추상화의 시작점이다. 인식론 혹은 일반철학에서 이런 추상화의 결과로 나온 것을 흔히 개념concept이라고 부른다. 실제 사물이 인식되어 인간의 사고속에 담겨지는 그 “무언가”를 개념이라고 호칭한다. 물론, 이 개념은 실제 사물과 연결되는 것도 있고, 아닌 것도 있지만 이 글에서 논하는 것은 범주를 넘어서므로 딱히 논하지는 않겠다.

객체지향 프로그래밍은 이 추상화의 과정을 거쳐 생성된 개념들을 코드로 옮긴다. 이때 작성된 코드가 객체의 설계도라고 볼 수 있는 클래스class인지, 아니면 객체의 첫 상태라고 볼 수 있는 프로토타입prototype인지에 따라 세부적인 형태는 달라질 수 있겠지만, 어쨌든 개념을 코드로 옮긴다는 점에서는 동일하다고 볼 수 있다.

다시 살짝 인식론으로 돌아가서 본다면, 인간이 하는 일이 사물을 통해 개념을 만들어내는 추상화의 작업만 있는 것은 아니다. 알고 있는 개념을 이용해 그에 부합하는 사물을 만들어내거나 모사하는 구체화의 작업도 존재한다. 객체지향 프로그래밍에서는 이 과정이 코드 실행단계라고 이야기할 수 있다. 코드로 옮겨진 개념들이 컴퓨터라는 기계를 통해 실행되면서, 실제로 객체가 생성되고 상호작용을 시작하는 것이다. 그리고, 이 상호작용을 통해 프로그래머의 의도를 표현하게 된다.

물론, 인간이 추상화를 어떤 방식으로 수행하는지와 그 결과물인 개념이 어떤 구성요소로 이루어져 있는지에 관해서는 이견이 많을 수 있겠지만, 객체지향 프로그래밍에서는 명확하게 정의되어 있다. 객체는 상태와 행위로 구성된다. 따라서, 그 객체를 개념화한 클래스 혹은 프로토타입 역시 상태와 행위로 구성된다. 이론적으로 본다면, 객체지향 프로그래밍 패러다임은 인간의 자연스러운 추상화에 의해 생성된 개념을 코드라는 형태로 써내려가기만 하면 손쉽고 자연스러운 소프트웨어 작성을 도모할 수 있다.

이론은 어디까지나 이론이다. 인간이 생각해낸 개념을 상태와 행위로 구성되는 개념만으로 표현이 힘든 것도 있거니와, A라는 프로그래머가 만든 개념이 불필요하게 복잡하고 이해하기 어려운 형태일 수도 있고, 또는 지나치게 단순하거나 한 개념에 너무 많은 것을 뭉뚱 그려놓은 (흔히 말하는 -스파게티-) 형태일 수도 있다. 이런 이론과 현실의 갭이 프로그래머의 능력을 나타내는 지표가 될 수 도 있겠지만, 객체지향 프로그래밍의 단점으로 바라볼 수 도 있다.

이 갭을 줄일 수 있는 가장 좋은 방법은 아마도 논리적-철학적 사고방식의 습관화가 아닐까 생각해본다. 어쩌면, 소프트웨어 개발자/프로그래머에게 가장 필요한 지식은 수학이라기 보다는 철학일 수 도 있을 것이다.

.. 이후는 다음 기회에 (우왕 길다)

ps. 꼴랑 이거 쓰는데 한달 걸렸어요. 쳇.
ps2. 레이아웃 깨지는 문제로 다시 엽니다. 🙂