본문 바로가기

메시징이 핵심이다 스몰토크가 말한 OOP

반응형

Dr. Alan Kay on the meaning of "object-oriented programming"
Dr. Alan Kay on the meaning of "object-oriented programming"

 

⚡ 한 줄 요약: 앨런 케이가 말한 OOP의 본질은 상속·클래스가 아니라 '메시지를 주고받는 느슨한 객체' — 마이크로서비스·액터 모델로 코드를 짜기 전에 이 관점부터 장착하라.

 

 

무슨 일인지

해커뉴스에서 앨런 케이(Alan Kay) 가 직접 "object-oriented programming"의 의미를 설명한 글이 다시 회자되고 있다.
케이는 'OOP'와 스몰토크(Smalltalk) 를 만든 당사자, 즉 이 용어의 원작자다.
그런 그가 남긴 말이 의외다.

"내가 오래전에 'object(객체)'라는 단어를 만든 걸 후회한다.
사람들이 덜 중요한 개념에 집중하게 만들었기 때문이다.
진짜 큰 아이디어는 메시징(messaging) 이다."

우리가 학교와 면접에서 외운 "OOP = 캡슐화·상속·다형성"은, 정작 창시자 기준으로는 곁가지라는 얘기다.

 

 

배경 — 케이가 말한 OOP의 3층

케이의 정의를 그대로 옮기면 OOP는 딱 세 가지다.
추상적이니 한 층씩 분해해 보자.

 

원문 표현 쉽게 말하면
① 메시징 only messaging 객체끼리 메시지만 주고받음. 내부 호출 아님
② 캡슐화 local retention, protection and hiding of state-process 상태를 밖에서 못 건드리게 완전히 숨김
③ 극단적 늦은 바인딩 extreme late-binding of all things "어떤 코드가 실행될지"를 런타임에 결정

 

핵심은 ①이다.
케이의 머릿속 모델은 세포(cell)인터넷이었다.
세포는 서로의 내부를 모른 채 화학 신호만 주고받고, 인터넷의 서버들은 상대 구현을 몰라도 패킷(메시지)만으로 협력한다.
즉 객체는 "데이터 + 함수 묶음"이 아니라, 독립적으로 살아 있는 작은 컴퓨터이고, 그것들이 메시지로 협상하는 게 OOP라는 것.

여기서 ②③이 따라온다.
내부를 완전히 숨겨야(②) 메시지로만 소통할 수 있고, 받는 쪽이 "이 메시지를 어떻게 처리할지" 런타임에 정해야(③) 보내는 쪽과 받는 쪽이 느슨하게 분리된다.

 

 

개발자에게 주는 의미

오늘날 우리가 짜는 OOP는 대개 클래스 계층 설계에 매몰돼 있다.
깊은 상속 트리, getter/setter 떡칠, extends 남발 — 케이 기준으로는 전부 "덜 중요한 개념"에 힘쓴 결과다.

반대로 메시징 관점은 지금 현업의 최신 트렌드와 정확히 맞닿아 있다.

  • 마이크로서비스 / 이벤트 기반 아키텍처: 서비스는 서로의 DB·내부를 모른 채 메시지(이벤트, REST, gRPC)로만 협력 → 케이가 말한 객체 그 자체
  • 액터 모델(Erlang/Elixir, Akka): 액터는 메일박스로 메시지만 받는다. 상태 공유 없음 → ①②의 교과서적 구현
  • 덕 타이핑·다형성: "타입이 뭐냐"가 아니라 "이 메시지에 반응하느냐" → ③ 늦은 바인딩

요지: 상속으로 코드를 묶을 생각부터 하지 말고, "이 객체가 어떤 메시지를 받느냐(공개 인터페이스)"부터 설계하라.
결합도가 내려가고 테스트·교체가 쉬워진다.

 

 

실무 적용 — '호출'이 아니라 '메시지'로

차이를 코드로 보자.
받는 쪽 타입을 몰라도, 메시지에 반응만 하면 동작한다(늦은 바인딩 + 캡슐화).

# ❌ 타입에 강결합 — "넌 Dog니까 이렇게 짖어"
def make_sound(animal):
    if isinstance(animal, Dog):
        return animal.bark()
    elif isinstance(animal, Cat):
        return animal.meow()

# ✅ 메시징 — "speak 메시지를 보낸다.
어떻게 처리할진 네 몫"
def make_sound(animal):
    return animal.speak()      # 누가 받든 speak에 반응만 하면 OK

class Dog:
    def speak(self): return "멍멍"
class Robot:                   # Animal 상속 안 함.
그래도 동작
    def speak(self): return "삐빅"

make_sound(Robot())            # → "삐빅"

make_sound는 받는 객체의 클래스·상속 계층을 전혀 모른다.
오직 "speak라는 메시지에 응답하는가"만 본다.
이게 케이가 말한 OOP의 결이다.
상속 트리를 늘리는 대신 메시지(인터페이스)를 좁고 명확하게 가져가면 된다.

 

 

체크포인트 — 그래서 뭘 해보면 되나

  • 설계 시작점 바꾸기: 새 클래스를 만들 때 extends ___부터 쓰지 말고, "이 객체가 받는 메시지(public 메서드) 목록" 을 먼저 종이에 적어라. 그게 진짜 계약이다.
  • 상속 → 합성 + 인터페이스: 깊은 상속이 보이면 "메시지로 위임"으로 바꿔라. 액터·이벤트 모델을 한 번 읽어보면 ①②③이 한 번에 잡힌다.
  • 용어 다시 정리: 면접에서 OOP 3대 특성을 묻거든 캡슐화·상속·다형성을 답하되, "창시자 앨런 케이는 메시징을 본질로 봤다" 한 줄을 덧붙이면 깊이가 다르다.

 

 

참고(출처)

반응형