객체지향으로 만들어진 객체는 능동적인가? 수동적인가?


어떤 책에서는 객체지향을 매우 능동적으로 서술하고 있다. 마치 객체들이 살아서 움직이면서 유기적으로 행동하는 것으로 묘사한다. 어떤 특정한 상태에서는 그것이 맞는 말이긴 하다. 하지만 내가 보는 객체지향의 세계는 상당히 수동적이다.


객체지향을 능동적으로 보는 관점에서 항상 시작은 "어느 객체가 무슨 할 일이 있을 경우"이다. 즉, 할 일이 있을 때 자기가 스스로 해야 할지, 남에게 시켜야 할지(위임)를 결정한다. 만약 해야 할 일이 크다면 위임될 가능성도 크다. 따라서 참조하는 객체에게 자신이 해야 할 일 일부 또는 전부를 시킨다. 따라서 해야 하는 일의 관점과 그 일을 하는 객체의 관점에서 보면 객체는 능동적인 것이 맞다.


하지만 객체지향 전체 세계를 놓고 보면 객체지향의 세계는 매우 수동적이다. 그 이유는 어떤 "이벤트"에 의해 객체가 동작하기 때문이다. 우리는 이 "이벤트"를 주로 메시지, 공개 함수, 공개 멤버 함수, 메소드, 인터페이스, API 등 다양한 이름으로 부른다. 절차지향 또는 구조적 언어에서 객체지향으로 넘어오면서 수동적인 것에서 능동적인 것으로 변화했다고 묘사하는 경우가 종종 있지만 결국 누군가가 시키지 않으면 일하지 않는 것이 기본이다. 맴버 함수 호출이 없는 경우 객체는 아무 일도 하지 않는다. 이것이 기본이다. 이벤트 없이 객체는 움직이지 않는다.


그러면 그 이벤트의 시작은 어디일까? 몇가지로 구분해보자.


1. 인터럽트

OS 레벨에서의 이벤트를 말한다. 통신, UI 조작(키보드나 마우스 이벤트), 타이머 등이 이에 해당된다. 이들은 여러 루트를 통해 이벤트를 객체에게 전달한다. 이러한 이벤트가 객체로 흘러 들어오는 순간 객체는 동작하게 된다. 그리고 이런 이벤트들은 아까 이야기 했던 공개 맴버 함수를 호출하는 형태로 이루어진다. 결국 객체는 시스템의 관점에서 보면 수동적인 것이다.


2. 쓰레드

쓰레드는 유일하게 객체가 능동적으로 보일 수 있는 부분이다. 쓰레드가 하는 일을 크게 나눠보면 두가지가 있는데, 하나는 이벤트를 기다리는 것, 하나는 주기적인 동작이다. 이벤트를 기다리는 것은 1번의 인터럽트와 크게 다를 바가 없다. 주기적인 동작은 일련의 동작들을 반복적으로 수행한다는 개념이다. 이것 정도가 그나마 능동적이라고 할 수 있겠다.


이 이야기를 꺼낸 이유는 간단하다. 무상태 프로그래밍을 수행하기 위해서 상태를 발생시키는 원인이 어디에 있는가를 알아보기 위해서다. 1번의 인터럽트의 경우 당연히 외부적인 요인이므로 상태를 발생시킨다. 그리고 우리가 다루었던 것처럼 외부적인 상태는 FactoryMethod 패턴, Holder 패턴 등을 이용하여 상태를 객체화 시킴으로써 해결할 수 있다. 


남은 것은 쓰레드인데 쓰레드가 어떤 상태를 계속 만들어 낸다고 해서 그것이 객체 세계 전체에 영향을 미치게 할 필요가 있을까? 이미 외부적인 상태에 대해 해결하는 방법을 알려 주었다. 그 방법을 쓰레드가 생성하는 상태에 적용하지 못할 이유가 있을까?


당연히 그렇게 하지 못할 이유는 전혀 없다. 어떻게 상태가 생성되었든 간에 그 상태가 발생한 객체는 여러 방법들을 이용해서 상태를 객체화 시킬 수 있다. 그러고 나면 모든 일은 객체와 객체간의 관계 문제로 바뀐다. 그리고 이 문제를 해결하는 해결책 역시 나와 있다. 상태 패턴, 전략 패턴 등이 바로 그것이다.


결국 객체 세계 내부에서는 (쓰레드를 제외하고는) 상태가 발생하지 않아야 한다.

Posted by 이세영2
,