시작하며
지난 글 우리의 코드가 스파게티인 이유에서 함수의 단점을 짚어보았습니다.
언급했듯이, 함수는 호출하지 않으면 절대로 동작하지 않습니다.
인터페이스와 함수로 구현한 객체는 수동적입니다.
객체의 수동적인 특성 때문에 객체간에는 상하관계가 강제됩니다.
이로 인해 프로그램 구조는 점점 경직되며 파악과 수정을 곤란하게 합니다.
'이벤트'라는 개념을 적절히 사용하면
이러한 문제들을 해결할 수 있습니다.
이번 글에서는 자세한 구현이나 코드를 소개함에 앞서
이벤트 기반 프로그래밍의 기본적인 개념을 살펴보고자 합니다.
이벤트 이해하기
우선 이벤트란 무엇일까요?
이벤트 기반 프로그래밍을 알려면 이벤트를 먼저 이해해야 합니다.
이벤트는 간단히 말하면 '일어난 사건'이라 할 수 있습니다.
누군가가 어떤 말을 했다거나,
다른 사람에게 돈을 이체했다거나 하는 사건들을 이벤트라 할 수 있습니다.
'일어난 사건'이라는 표현이 과거형이라는 점에 주목하세요.
미래에 일어날 수도 일어나지 않을 수도 있는 일이나
실제로 실행될지 안 될지 모르는 명령은 이벤트가 될 수 없습니다.
누군가 내 이름을 부르면 고개를 돌리듯
하나의 사건은 또 다른 사건을 유발합니다.
이벤트는 새로운 이벤트로 이어집니다.
우리는 이벤트의 흐름 속에서 살아가고 있습니다.
연관된 이벤트의 흐름을 이용하면
더 큰 사건을 표현하는 것이 가능합니다.
예를 들어, 배가 고파 배달 음식을 주문할 때를 생각해봅시다.
음식 배달이라는 큰 사건을 여러 작은 이벤트의 흐름으로 나타낼 수 있습니다.
이벤트 기반 프로그래밍은 이런 이벤트의 흐름을 코드로 표현하는 것입니다.
그다지 어려운 개념은 아닙니다.
이벤트 기반 프로그래밍이 객체 지향에서만 가능한 것은 아니지만,
객체지향과 결합되면 어떤 모습일까요?
함수 객체
편의상 기존처럼 함수와 인터페이스를 이용한 객체를 함수 객체,
이벤트 기반으로 동작하는 객체를 이벤트 객체라 하겠습니다.
함수 객체를 먼저 살펴보면,
함수 객체는 다음과 같은 흐름을 가집니다.
객체는 상위 객체에게 명령을 받고
더 하위에 있는 객체에게 다시 명령을 내리며
필요하다면 스스로의 상태를 변경하고
그 결과를 다시 상위 객체에게 보고합니다.
이는 하위 객체에 대한 제어권과 책임을 가짐과 동시에
자신에 대한 제어권과 책임은 상위 객체에게 넘긴 것과 같습니다.
이런 구조는 많은 문제를 발생 시킵니다.
우선,
객체가 스스로의 작동 방식을 변경하려 한다면
상위 객체의 허락을 받아야 합니다.
책임, 즉 권한을 상위 객체에게 넘겼기 때문입니다.
위의 그림에는 상위 객체가 하나 밖에 없지만
실제로는 수십개가 될 수도 있습니다.
심지어 상위 객체는 나도 모르게 점점 늘어납니다.
수십 번 허락을 받아야 하는 코드를 바꾸기는 정말 어렵습니다.
한편,
상위 객체는 함수 호출의 결과를 확인하고
후속 처리까지 책임져야 합니다.
어떤 큰 작업을 처리하려 할 때,
상위 객체는 우선 작업을 여러 소작업으로 쪼개고
각 소작업을 담당하는 여러 하위객체에게 순서대로 명령을 내립니다.
결국, 객체의 계층 구조에서 하위 객체로 갈수록
파편적이고 자잘한 작업만 수행하게 됩니다.
상위 객체일수록 큰 책임, 하위 객체일수록 작은 책임을 가지는 것입니다.
이벤트 객체
이번엔 이벤트 객체를 살펴보겠습니다.
이벤트 객체의 동작 흐름은 다음과 같습니다.
이벤트 객체는 이벤트에 반응하여
필요하다면 또 다른 이벤트를 발행하는 객체라고 할 수 있습니다.
이벤트 객체는 함수 객체와는 다른 특징을 가지고 있습니다.
1. 이벤트 객체는 능동적입니다
이벤트 객체는 어떤 이벤트에 반응할지,
어떻게 반응할지,
반응의 결과로 또 다른 이벤트를 발행할지 말지
객체가 스스로 선택하는 형태입니다.
이벤트 객체는 자기 자신에 대한 모든 책임과 권한을 가집니다.
2. 이벤트 객체는 독립적입니다
이벤트 객체는 다른 객체와 직접적인 관계를 맺지 않습니다.
단지 어떤 이벤트에 반응하고 어떤 이벤트를 발행할지에만 관심이 있습니다.
이벤트A에 반응하기로 정했다면,
이벤트A를 누가 발행하는지는 관심이 없습니다.
마찬가지로 이벤트B를 발행하기로 정했다면,
누가 이벤트B에 반응할지에 관해서는 관심이 없습니다.
이벤트 객체는 서로 간섭하지 않습니다.
3. 이벤트 객체는 수평적입니다
이벤트 객체 간에는 함수 객체와 달리 상하간 위계가 존재하지 않습니다.
각 객체가 완벽하게 스스로를 책임지고 서로 간섭하지 않기 때문입니다.
이벤트 객체는 명령과 통제가 아니라 이벤트를 통한 협력을 활용하여
프로그램 전체의 목표를 달성합니다.
이벤트 객체의 협력은 수직적 협력이 아니라 수평적 협력입니다.
이벤트 객체 코드는 깔끔합니다
저는 깔끔한 코드를 좋아합니다.
이벤트 객체의 능동적이고 독립적인 특성은 코드를 깔끔하게 만드는데 큰 도움이 됩니다.
특히, 코드를 수정할 때 다른 클래스 코드를 살펴보지 않아도 됩니다.
함수 객체의 코드를 고칠 때 다른 클래스의 코드까지 들여다 봐야 하는 이유는
정작 책임이 다른 상위 객체에게 있기 때문입니다.
이벤트 객체는 스스로를 온전히 책임집니다.
어떤 이벤트에 반응할지, 어떻게 반응할지, 어떤 이벤트를 발행할지
모두 한 클래스 안에서 스스로 정의하게 됩니다.
함수 객체와 다르게,
하위 객체 클래스를 멤버 변수나 멤버 리스트로 잔뜩 가지고 있을 필요도 없습니다.
정말 자기에게 필요한 함수 객체만 하위 객체로 가지고 있게 됩니다.
한번 이벤트 방식의 코드를 작성해보시면 정말 편하다는 것을 느끼실 수 있을 겁니다.
이어지는 글에서 실제 코드 예시와 함께 더 자세히 설명드리도록 하겠습니다.
마치며
이번 글에서는
이벤트 기반 프로그래밍이 무엇인지
그리고 이벤트 객체가 어떤 특징을 가지고 있는지
알아보았습니다.
대략 감을 잡으셨을 수도 있지만
너무 개념적이어서 모호할 수도 있을 듯 합니다.
다음 글에서는
이벤트와 이벤트 객체를 작성하는 데에 있어
간단한 구현 예시와 지켜야할 원칙을 다뤄볼까 합니다.
이벤트 기반 프로그래밍에 관심이 있으시다면
구독하여 이벤트 기반 프로그래밍 시리즈를 지켜봐 주시기 바랍니다.
또한 다른 의견이나 궁금한 점이 있으시다면 댓글로 말씀해주세요.
토의는 언제나 환영합니다.
여기까지 읽어주셔서 감사합니다.