이 글은 객체지향 설계 개념을 차례로 살펴보는 작은 시리즈의 여섯 번째 글입니다.
- 메서드 시그니처 - 계약에 남긴 서명(https://likebnb.tistory.com/183)
- 계약 - 자유를 줄이고 예측가능성을 만드는 방식(https://likebnb.tistory.com/184)
- 인터페이스 - 경계를 지키는 이름(https://likebnb.tistory.com/185)
- 프로토콜 - 상호작용의 질서(https://likebnb.tistory.com/186)
- 스테이트 머신 - 시공간의 맥락(https://likebnb.tistory.com/187)
- 이벤트 - 코드의 흐름을 삼키다(https://likebnb.tistory.com/188)
처음 파워빌더로 프로그램을 열어보았을 때, 나는 코드의 흐름을 찾을 수 없었다.
프로그램은 분명 동작하고 있었지만, 어디서 시작해 어디로 이어지는지 한눈에 보이지 않았다.
그때까지 나는 파스칼로 프로그램을 만들고 있었고, 얼마 지나지 않아 파스칼 기반의 델파이도 함께 사용하기 시작했다. 두 언어 모두 절차적인 흐름을 비교적 또렷하게 드러내는 구조를 갖고 있었다. 프로그램의 시작점이 있고, 함수와 프로시저를 따라가면 코드의 흐름이 자연스럽게 이어졌다.
그런데 파워빌더에서 만난 프로그램은 달랐다.
버튼을 누르면 화면이 바뀌고, 데이터를 입력하면 저장이 되고, 창이 열리고 닫혔다. 프로그램은 분명 살아 움직이고 있었다. 하지만 그 모든 동작이 어디서 시작되어 어디로 흘러가는지 한눈에 보이지 않았다. 익숙했던 main 함수도 없고, 위에서 아래로 이어지는 절차도 보이지 않았다.
코드는 분명 존재하는데, 흐름은 보이지 않았다.
나중에서야 그 이유를 이해하게 되었다.
그 프로그램은 더 이상 코드의 흐름으로 움직이지 않았기 때문이다.
그 구조를 움직이고 있던 것은 이벤트(event)였다.
지금까지 이 글의 앞선 이야기에서는 몇 가지 개념을 차례로 살펴보았다.
메서드 시그니처는 코드 위에 드러난 서명이었다.
컨트랙트는 그 서명이 담고 있는 예측가능성, 즉 약속이었다.
인터페이스는 그 약속들이 모여 형성된 경계였다.
프로토콜은 그 경계 위에서 이루어지는 상호작용의 질서였다.
그리고 상태 머신은 그 상호작용 속에서 객체가 겪게 되는 상태변화를 설명하는 시공간의 맥락이었다.
이제 마지막으로 남은 질문이 하나 있다.
그 모든 변화는 어디에서 시작되는가.
그 답이 바로 이벤트다.
이벤트는 어떤 일이 발생했다는 사실을 알리는 신호다.
버튼이 눌렸을 때
마우스가 움직였을 때
데이터가 도착했을 때
타이머가 만료되었을 때
시스템 어딘가에서 어떤 변화가 일어나면, 그 사실이 하나의 이벤트로 전달된다. 그리고 객체는 그 이벤트에 반응하여 자신의 상태를 바꾸거나 다른 객체와 상호작용을 시작한다.
이 점에서 이벤트는 어떤 의미에서 방아쇠(trigger)와도 비슷하다.
객체가 스스로 살아 움직이는 존재라기보다는,
어떤 사건이 발생했을 때 그에 반응하도록 설계된 존재라면,
이벤트는 바로 그 반응을 촉발하는 신호이기 때문이다.
그래서 이렇게 말할 수도 있다.
이벤트는 그 모든 변화를 촉발하는 트리거다.
절차적인 프로그램에서는 흐름이 코드 속에 드러나 있다.
어떤 함수가 호출되고,
그 함수 안에서 또 다른 함수가 호출되고,
그 호출의 사슬을 따라가면 프로그램의 흐름을 비교적 쉽게 추적할 수 있다.
하지만 이벤트 기반 구조에서는 상황이 다르다.
어떤 객체가 어떤 코드를 실행할지는 미리 정해진 호출 흐름에 의해 결정되지 않는다. 대신 시스템 어딘가에서 발생한 이벤트가 객체에게 전달되고, 그 이벤트를 처리하는 핸들러가 실행된다.
그래서 프로그램의 동작은 더 이상 하나의 선형적인 흐름으로 설명되지 않는다.
이벤트가 발생하고,
객체가 반응하고,
상태가 바뀌고,
또 다른 이벤트가 발생한다.
프로그램은 이런 상호작용의 연쇄 속에서 움직인다.
이 지점에서 처음 파워빌더를 접했을 때의 당혹스러움이 조금 이해된다.
나는 코드 속에서 프로그램의 흐름을 찾으려고 했다.
하지만 그 구조에서는 애초에 그런 흐름이 드러나지 않도록 설계되어 있었다.
코드의 흐름은 사라진 것이 아니었다.
그 흐름은 이벤트와 객체의 구조 속으로 삼켜져 있었던 것이다.
객체지향 설계에서 객체는 단순히 데이터를 담는 상자가 아니다.
객체는 상태를 가지고 있고, 그 상태는 끊임없이 변화한다. 그리고 그 변화는 대부분 어떤 사건에 대한 반응으로 일어난다.
이벤트는 바로 그 반응의 출발점이다.
어떤 사건이 발생하고,
객체가 그것을 받아들이고,
자신의 상태를 바꾸고,
또 다른 상호작용을 만들어낸다.
그 과정 속에서 시스템은 살아 움직인다.
그래서 어쩌면 이렇게 말할 수도 있다.
객체가 사는 세계에서 프로그램은 더 이상 단순한 코드의 흐름이 아니다.
그것은 이벤트와 상태 변화가 만들어내는 하나의 살아있는 구조다.
그리고 이벤트는,
그 모든 움직임을 시작하게 만드는 작은 방아쇠다.
이 시리즈의 처음에서 우리는 코드 위에 남겨진 하나의 서명(signature)에서 이야기를 시작했다.
그 서명은 약속이 되었고,
약속은 인터페이스가 되었고,
인터페이스는 상호작용의 질서를 만들었다.
그 질서는 상태의 변화를 통해 시스템의 동작을 설명하게 되었고,
마침내 우리는 그 모든 변화를 시작하게 만드는 사건, 이벤트에 도달했다.
이제 다시 처음의 질문으로 돌아가 보면,
객체가 사는 세계에서 프로그램은 더 이상 위에서 아래로 흐르는 코드가 아니다.
그것은 수많은 사건과 반응이 얽혀 만들어지는 하나의 구조다.
그리고 어느 순간 우리는 깨닫게 된다.
코드의 흐름이 사라진 것이 아니라,
이벤트가 그 흐름을 삼켜버렸다는 사실을.
'일하는 중에' 카테고리의 다른 글
| 학교에서 가르쳐주지 않은 필요·충분조건의 본질 (feat. 블룸 필터) (1) | 2026.05.18 |
|---|---|
| 로컬 LLM, 왜 지금 다시 봐야 하는가 - OpenClaw와 함께 만드는 스트림 분석 아키텍처 (0) | 2026.04.17 |
| 객체가 사는 법 #5. 스테이트 머신 - 시공간의 맥락 (0) | 2026.03.24 |
| 객체가 사는 법 #4. 프로토콜 - 상호작용의 질서 (0) | 2026.03.20 |
| 객체가 사는 법 #3. 인터페이스 - 경계를 지키는 이름 (0) | 2026.03.18 |