Skip to content
Historical revision
객체지향 프로그래밍2026-05-10 21:21 UTC
rev_53a1aa8316d14d21bdf34ad9f3258d0b

객체지향 프로그래밍

객체지향 프로그래밍

들어가기에 앞서서

사람들은 흔히 디자인 패턴을 만능 해결책이라 말한다. OOP가 만들어지고 GoF(4인방)의 디자인 패턴이라는 책이 일종의 복음서로 자리잡은 지금, 많은 개발자는 패턴 책을 펼치며 구조 다이어그램만 보고 코드를 작성한다. 그 결과 유연성 없는 경직된 구현이 나오곤 한다.

우리는 디자인 방법론과 패턴을 배우는 데 있어서 '도식적인 이해'와 '실질적 경험' 사이의 괴리 속에서 항상 흔들린다. 크리스토퍼 알렉산더가 말했듯, 디자인의 실체에서 디자인 방법을 분해한다는 것은 결국 실체 없는 허상만 이야기하게 되는 것이다.1

사실 패턴을 이야기하기 전에 Idiom 등 여러 갈래를 짚을 수 있지만, 그 이야기는 프로그래밍 이디엄 문서에서 다루기로 하고 이 글에서는 패턴을 둘러싼 OOP의 정체를 논하고자 한다.


객체지향 프로그래밍(Object-Oriented Programming, OOP)은 데이터와 그 데이터를 조작하는 절차를 객체(Object)라는 단위로 묶어 프로그램을 구성하는 프로그래밍 패러다임이다. 절차적 프로그래밍에서 분리되어 있던 데이터와 함수를 하나의 단위로 캡슐화하는 것이 핵심이며, 1960년대 Simula 언어에서 시작되어 현재 산업계에서 가장 널리 쓰이는 패러다임 중 하나로 자리잡았다.

중요한 전제
현재 우리가 통용하는 OOP는 앨런 케이가 본래 의도한 메시지 기반 객체지향이 아니라, Simula에서 비롯되어 버야네 스트로스트룹, 피터 웨그너, 버트런드 마이어, 그레디 부치 등을 거쳐 산업계에서 점진적으로 형성된 클래스 기반 OOP다. 단일 저자나 단일 책의 산물이 아니라, 1980년대 후반~1990년대 초반에 걸친 합작물이며, 학습서·인터뷰·디자인 패턴 서적에서 만나는 OOP는 이 합작물의 후일 단순화된 형태다.

다른 뜻에 대해서는 다음을 참고:

  • 알랜 케이가 제창한 본래의 객체지향: 메시지 기반 객체지향

  • 프로토타입 기반 객체지향: 프로토타입 기반 프로그래밍

목차

  1. 들어가기에 앞서서

  2. 개요

  3. 역사

  4. 부치의 객체 모델: 4 major + 3 minor

  5. OOP 3요소(캡슐화·상속·다형성)의 출처

  6. 메시지 기반 OOP와 클래스 기반 OOP

  7. 핵심 개념

  8. 설계 원칙

  9. 디자인 패턴

  10. 장점과 단점

  11. 비판

  12. 같이 보기

  13. 각주

개요

OOP의 정의는 시기와 사람에 따라 미묘하게 다르다. 단일한 정의가 존재하지 않으며, 여러 정의가 공존한다.

  • 앨런 케이 (1967, 2003 재정의): 메시징, 상태와 처리의 로컬 보존·은폐, 극단적인 늦은 바인딩을 핵심으로 본다.

  • 그레디 부치 (1991): 4 major elements (추상화, 캡슐화, 모듈화, 계층) + 3 minor elements (타이핑, 동시성, 영속성)로 구성된 부치 객체 모델을 제시한다.

  • 버트런드 마이어 (1988, OOSC): 설계에 의한 계약(Design by Contract)을 중심으로 한 형식적 OOP 정의.

  • 피터 웨그너 (1987, OOPSLA): object-based, class-based, object-oriented를 단계적으로 구분.

  • 이후 통속적 산업계 정의: 위 흐름을 단순화한 캡슐화·상속·다형성의 3 pillars (단일 저자 출처가 명확하지 않다).

이 정의들의 간극은 단순한 학술적 논쟁이 아니라, 실무에서 OOP를 어떻게 적용할지 결정하는 출발점이 된다.

역사

우리가 지금 이야기하는 패턴이 나오게 된 배경

1962~1967년: Simula와 클래스의 등장

Simula (1962)와 Simula 67 (1967)에서 클래스 개념이 처음 도입되었다. 노르웨이의 크리스텐 뉘고르와 올레요한 달이 이산 사건 시뮬레이션 목적으로 개발했다. 이후 모든 클래스 기반 OOP의 원류가 된다.

1967년: 앨런 케이의 출발점

객체지향 프로그래밍이라는 용어 자체의 첫 주창자는 앨런 케이로, 그는 1967년 초에 "object-oriented"라는 표현을 사용하였다. 이후 제록스 PARC에서 Smalltalk를 통해 자신의 비전을 구현했다.

2003년: 케이의 자기 정정

케이는 후일 2003년 Stefan Ram에게 보낸 이메일에서 자신이 말한 객체지향 프로그래밍이 다음 세 가지였다고 못 박았다.2

  1. 메시징 (Messaging)

  2. 상태와 처리의 로컬 보존, 보호, 은폐 (Local retention and protection and hiding of state-process)

  3. 극단적인 늦은 바인딩 (Extreme late-binding of all things)

쉽게 말하면, 케이가 생각한 객체는 작은 컴퓨터 같은 것이다. 각 객체가 독립적으로 존재하고, 서로 메시지를 주고받으며 협력하는 구조였다. 클래스 계층을 설계하는 것보다 "객체 사이에 어떤 메시지가 오가는가"가 핵심이었다.

하지만 이렇게 이야기하면 우리가 생각하는 그 OOP 개념이 아니다. 그럼 우리가 이야기하는 개념은 어디서 나온 것일까?

1980년대 후반~1990년대 초반: 산업계 OOP의 형성

현재 우리가 쓰는 OOP는 한 사람의 정의가 아니라, 1980년대 후반부터 1990년대 초반까지 여러 인물의 합작으로 점진적으로 형성된 것이다.

1985년: 스트로스트룹과 C++

버야네 스트로스트룹이 Simula의 클래스 모델을 C 언어에 이식한 C++을 발표했다.3 C++은 클래스 기반 OOP를 산업계에 침투시킨 첫 번째 결정적 언어였고, 이후 모든 메인스트림 OOP 언어의 사실상의 기준점이 되었다.

1987년: 웨그너의 분류

피터 웨그너는 OOPSLA 1987 논문 "Dimensions of Object-Based Language Design"에서 다음과 같은 단계적 구분을 제시했다.4

  • 객체 기반 (Object-based): 객체 + 캡슐화 (예: Ada, Modula-2)

  • 클래스 기반 (Class-based): 객체 기반 + 클래스 (예: CLU)

  • 객체지향 (Object-oriented): 클래스 기반 + 상속 (예: Smalltalk, C++)

이 분류는 후일 통속적 OOP 3요소 형성에 직접적인 영향을 미친다.

1988년: 마이어와 OOSC

버트런드 마이어가 Object-Oriented Software Construction (OOSC, 1988)을 발표했다. 자신이 설계한 Eiffel 언어를 기반으로 설계에 의한 계약(Design by Contract), 불변식, 클래스 인바리언트 등 OOP의 형식적 토대를 정립했다. 메이어의 OOSC는 부치의 OOAD와 함께 1990년대 OOP 교육의 양대 산맥이었다.

1991년: 부치의 OOAD

그레디 부치가 Object-Oriented Analysis and Design with Applications (1991)을 발표했다.5 이 책에서 부치는 OOP를 다음과 같이 정의했다 (p.37).

"Object-oriented programming is a method of implementation in which programs are organized as cooperative collections of objects, each of which represents an instance of some class, and whose classes are all members of a hierarchy of classes united via inheritance relationships."

요약하면 다음의 세 명제다.

  1. OOP는 알고리즘이 아닌, 객체를 논리적 구성 요소로 사용한다.

  2. 각 객체는 어떤 클래스의 인스턴스이다.

  3. 클래스는 상속 관계로 서로 연결된다.

다만 부치의 진짜 기여는 위 정의보다 객체 모델 (4 major + 3 minor)과 시각적 표기법(Booch notation)에 있다. 자세한 내용은 부치의 객체 모델: 4 major + 3 minor 절 참고.

1994년: GoF와 패턴의 시대

위와 같은 1980~90년대 클래스 기반 OOP의 정착을 배경으로, 1994년 하나의 거대한 프로그래밍 고전이 나온다. 바로 GoF의 디자인 패턴이다. 에리히 감마, 리처드 헬름, 랄프 존슨, 존 블리시디스 4인이 저자였기에 Gang of Four라 불린다.

GoF는 크리스토퍼 알렉산더의 패턴 언어 (A Pattern Language, 1977)에서 영감을 받았으나, 정작 알렉산더가 경고한 "방법론의 도식화"라는 함정에 빠지는 아이러니를 낳았다. 패턴이 ""가 아니라 "무엇을"의 문제로 환원되는 순간, 다이어그램만 외워 코드에 욱여넣는 풍토가 생겨난 것이다. 자세한 내용은 패턴의 도식화 함정 문서 참고.

1995년 이후: Java와 엔터프라이즈 정착

Java (1995)와 후일의 C샵 (2002)은 클래스 기반 OOP를 언어 차원에서 강제하다시피 했다. 모든 코드가 클래스 안에 있어야 하는 Java의 설계는 엔터프라이즈 소프트웨어 진영의 표준 패러다임으로 굳어졌다.

2000년대 이후: 재평가

함수형 프로그래밍의 부상, 데이터 지향 설계의 등장으로 OOP의 한계가 본격적으로 논의되기 시작했다. 알랜 케이 본인이 클래스 기반 OOP를 자신의 의도와 다르다고 거리를 두기 시작한 것도 이 시기다.

부치의 객체 모델: 4 major + 3 minor

부치의 1991년 책 2장 「The Object Model」은 객체 모델의 구성 요소를 다음과 같이 명시한다.56

분류

요소

설명

Major (필수)

추상화 (Abstraction)

본질적 특성을 추출

Major (필수)

캡슐화 (Encapsulation)

추상화의 내부 은폐

Major (필수)

모듈화 (Modularity)

응집도 높고 결합도 낮은 단위로 분해

Major (필수)

계층 (Hierarchy)

"is-a" 관계와 "part-of" 관계의 위계

Minor (선택)

타이핑 (Typing)

추상 데이터 타입에 기반한 타입 안전성

Minor (선택)

동시성 (Concurrency)

활성 객체와 비활성 객체의 구분

Minor (선택)

영속성 (Persistence)

시간과 공간을 가로지르는 객체 상태 보존

여기서 주목할 점은 다음과 같다.

  • 부치는 "다형성(Polymorphism)"을 객체 모델의 독립된 요소로 명시하지 않았다. 다형성은 계층(Hierarchy) 안에 함의되어 있을 뿐이다.

  • 부치는 "상속"을 단독 요소로 두지 않고 "계층"의 한 형태로 포섭한다. 계층은 상속 외에 합성("part-of")까지 포함하는 더 넓은 개념이다.

  • 모듈화, 동시성, 영속성 같은 소프트웨어 공학 차원의 개념이 객체 모델에 명시적으로 들어 있다는 점에서, 부치 모델은 통속적 3 pillars보다 풍부하다.

따라서 부치의 진짜 모델과 우리가 학원이나 인터뷰에서 만나는 "3요소" 사이에는 적지 않은 거리가 있다.

OOP 3요소(캡슐화·상속·다형성)의 출처

흔히 OOP의 3요소(혹은 3 pillars)로 언급되는 캡슐화·상속·다형성은 단일 저자가 정한 정의가 아니라, 산업계에서 점진적으로 굳어진 통속적 정식이다.

형성 과정

  1. Simula 67 (1967): 클래스, 인스턴스, 상속을 언어 차원에 도입.

  2. Smalltalk (1972~): 캡슐화와 다형성을 메시지 패싱으로 구현.

  3. 피터 웨그너 (1987): "객체 기반" → "클래스 기반" → "객체지향"의 단계적 구분 제시. 상속이 객체지향을 다른 패러다임과 구분 짓는 결정적 요소임을 명확히 함.4

  4. C++ 진영 (1985~1990년대): 산업 교육 자료에서 "캡슐화·상속·다형성을 모두 갖춘 것이 진정한 OOP"라는 정식이 통용되기 시작. 대표적으로 다음과 같은 진술이 흔하다.

    캡슐화만 사용하는 것 (즉, 클래스를 정의하고 사용하되 상속이나 다형성은 쓰지 않는 것)은 흔히 객체 기반 프로그래밍이라고 부른다. 진정한 OOP를 실천하려면 세 'pillars'(캡슐화·상속·다형성)를 모두 사용해야 한다.7

  5. Java (1995~) 교과서 시대: 위 정식이 표준 교육 자료에 정착.

출처에 관한 주의

  • "3요소"는 부치의 발명이 아니다. 부치 책에는 4 major + 3 minor 모델이 있을 뿐이다.

  • "3요소"는 케이의 정의도 아니다. 케이의 정의는 메시징·캡슐화·동적 바인딩이다.

  • "3요소"는 한 권의 책으로 추적되지 않는, 산업계의 합의된 통속적 정식이다.

이 점을 인식하지 못하면 OOP의 역사를 한 사람(부치)의 책으로 환원하는 오류에 빠진다.

메시지 기반 OOP와 클래스 기반 OOP

OOP는 사실상 두 갈래의 흐름으로 분기되어 있다.

구분

메시지 기반 OOP

클래스 기반 OOP

출발점

Smalltalk (1972)

Simula 67 (1967)

단위

메시지를 주고받는 작은 컴퓨터

클래스의 인스턴스

핵심

메시징, 동적 바인딩

클래스, 상속, 합성

결합도

극단적 늦은 바인딩

컴파일 타임 타입 결정 (대체로)

대표 인물

앨런 케이

크리스텐 뉘고르, 버야네 스트로스트룹, 버트런드 마이어, 그레디 부치

대표 언어

Smalltalk, Erlang, Self, Objective-C

C++, Java, C샵, Eiffel

사상적 후예

액터 모델, ECS의 메시지 측면

엔터프라이즈 OOP, GoF의 디자인 패턴

요점
두 갈래는 인적 대립이 아니라 패러다임의 분기다. 케이와 부치는 서로 다른 문제를 풀고 있었다. 케이는 다이나북이라는 미래의 개인 컴퓨팅을 상상하며 느슨한 결합 시스템을 설계하려 했고, 부치는 복잡 시스템(Ada 기반 군용 소프트웨어 등)의 분석과 설계 방법론을 정립하려 했다. 둘은 같은 용어("OOP")를 썼지만, 다른 종(種)의 패러다임을 만들고 있었던 것이다.

핵심 개념

본 섹션의 개념은 모두 클래스 기반 OOP를 기준으로 서술한다.

클래스와 객체

  • 클래스: 객체를 만들기 위한 청사진. 데이터 필드와 메서드를 정의한다.

  • 객체: 클래스의 인스턴스. 메모리상에 실체화된 단위.

  • 메시지: 객체 간 상호작용 수단. 클래스 기반 OOP에서는 보통 메서드 호출로 구현되지만, 케이의 본래 의미는 더 느슨한 결합을 의도했다.

통속적 4대 특성

캡슐화 (Encapsulation)

관련 데이터와 메서드를 하나의 단위로 묶고, 내부 구현을 외부로부터 정보 은닉하는 메커니즘.

public class BankAccount
{
    private decimal balance;

    public void Deposit(decimal amount)
    {
        if (amount <= 0) return;
        balance += amount;
    }

    public decimal GetBalance() => balance;
}

자세한 내용은 캡슐화 문서 참고.

상속 (Inheritance)

한 클래스가 다른 클래스의 속성과 메서드를 물려받는 메커니즘. 코드 재사용을 위한 수단으로 쓰이지만, 현대에는 합성(Composition)이 권장되는 경우가 많다.

상속 남용에 대한 경고: "상속보다 합성"(Composition over Inheritance)은 GoF의 디자인 패턴 책에서 강조한 원칙이다. 다이아몬드 문제, 리스코프 치환 원칙 위반 등이 상속 남용의 부작용이다.

다형성 (Polymorphism)

동일한 인터페이스로 서로 다른 구현을 호출할 수 있는 능력. 다음과 같이 분류된다.

  • 서브타입 다형성 (Subtype polymorphism): 상속/인터페이스 기반

  • 애드혹 다형성 (Ad-hoc polymorphism): 메서드 오버로딩

  • 파라메트릭 다형성 (Parametric polymorphism): 제네릭/템플릿

추상화 (Abstraction)

복잡한 시스템에서 본질적인 특성만을 추출하여 표현하는 행위. 추상 클래스와 인터페이스가 대표적인 도구다.

설계 원칙

SOLID 원칙

로버트 마틴이 정립한 OOP 설계 5대 원칙.

약어

원칙

설명

S

단일 책임 원칙 (SRP)

클래스는 하나의 변경 이유만 가져야 한다

O

개방-폐쇄 원칙 (OCP)

확장에는 열려 있고 수정에는 닫혀 있어야 한다

L

리스코프 치환 원칙 (LSP)

자식 타입은 부모 타입을 대체할 수 있어야 한다

I

인터페이스 분리 원칙 (ISP)

클라이언트는 사용하지 않는 인터페이스에 의존하지 않아야 한다

D

의존성 역전 원칙 (DIP)

추상에 의존하고 구체에 의존하지 않는다

기타 원칙

  • GRASP (General Responsibility Assignment Software Patterns)

  • DRY 원칙 (Don't Repeat Yourself)

  • KISS 원칙 (Keep It Simple, Stupid)

  • YAGNI (You Aren't Gonna Need It)

  • 디미터 법칙 (Law of Demeter)

  • 설계에 의한 계약 (Design by Contract) — 버트런드 마이어

디자인 패턴

OOP의 반복되는 설계 문제에 대한 정형화된 해법. GoF의 디자인 패턴 (1994)이 출발점이다. 클래스 기반 OOP의 직접적 산물이라는 점에 유의해야 한다 — 케이의 메시지 중심 OOP에서는 GoF 패턴 다수가 무의미하거나 다른 형태를 띤다.

분류

대표 패턴

생성

싱글톤 패턴, 팩토리 메서드 패턴, 추상 팩토리 패턴, 빌더 패턴, 프로토타입 패턴

구조

어댑터 패턴, 데코레이터 패턴, 프록시 패턴, 퍼사드 패턴, 브릿지 패턴, 컴포지트 패턴

행위

전략 패턴, 옵저버 패턴, 커맨드 패턴, 상태 패턴, 방문자 패턴, 책임 연쇄 패턴

자세한 분류 체계는 디자인 패턴 인덱스 참고.

장점과 단점

장점

  • 현실 세계 모델링에 직관적이다.

  • 코드 재사용을 촉진한다.

  • 적절히 설계된 경우 유지보수성이 향상된다.

  • 대규모 팀 개발에 적합하다.

  • 풍부한 디자인 패턴 자산을 활용할 수 있다.

단점

  • 과잉 추상화로 인한 복잡도 증가

  • 객체 생성 비용 (메모리 단편화, GC 압박)

  • 데이터 지역성 저하 (cf. 데이터 지향 설계)

  • 메서드 호출 오버헤드 (가상 함수 테이블)

  • 동시성 처리 시 공유 가변 상태 문제

비판

패턴 도식화의 함정

서두에서 언급했듯, 가장 근본적인 비판은 패턴이 도식으로 환원되는 순간 알렉산더가 경고한 "실체 없는 허상"이 된다는 점이다. GoF 다이어그램만 보고 코드에 끼워 맞추는 행위는 패턴 매칭 안티패턴이라 불린다.

함수형 진영의 비판

조 암스트롱(Erlang 창시자)은 "객체지향의 문제는 자신이 가진 환경 전체를 끌고 다닌다는 것이다. 바나나를 원했는데 바나나를 든 고릴라와 정글 전체를 받게 된다"고 비판했다.8

함수형 프로그래밍 진영은 가변 상태와 부수 효과가 OOP의 본질적 결함이라고 본다. 참조 투명성이 보장되지 않으므로 추론이 어렵다는 것이다.

데이터 지향 설계 진영의 비판

마이크 액튼은 CppCon 2014 발표에서 OOP가 캐시 미스를 유발하는 데이터 레이아웃을 강요한다고 지적했다. AoS vs SoA 논쟁이 대표적이다. 게임 개발과 고성능 컴퓨팅에서는 Entity Component System 같은 대안이 부상했다.

알랜 케이의 자기비판

원조 OOP 명명자인 알랜 케이는 현대의 클래스 기반 OOP가 자신이 의도한 메시지 패싱 중심 모델과 다르다며 거리를 두었다. 케이가 본래 의도했던 OOP는 액터 모델에 더 가깝다.

같이 보기

  • 디자인 패턴

  • GoF의 디자인 패턴

  • 크리스토퍼 알렉산더

  • 패턴 언어

  • 프로그래밍 이디엄

  • 부치 객체 모델

  • 설계에 의한 계약

  • 웨그너 분류

  • 함수형 프로그래밍

  • 절차적 프로그래밍

  • 데이터 지향 설계

  • Entity Component System

  • 액터 모델

  • 프로토타입 기반 프로그래밍

  • 다중 패러다임 언어

  • 도메인 주도 설계

외부 링크


분류: 프로그래밍 패러다임 | 소프트웨어 공학 | 컴퓨터 과학 | 패턴 인덱스 | 교육 자료

각주

  1. Alexander, Christopher. "The Timeless Way of Building", 1979. 디자인 방법을 실체에서 분리하면 허상이 된다는 논의는 본 저서의 핵심 주장이다.
  2. Kay, Alan. Email to Stefan Ram, July 23, 2003. 케이는 본 이메일에서 "OOP라는 용어는 내가 만들었지만, 거기에 C++은 들어 있지 않았다"는 취지의 발언을 했다.
  3. Stroustrup, Bjarne. "The C++ Programming Language", 1st edition, Addison-Wesley, 1985.
  4. Wegner, Peter. "Dimensions of Object-Based Language Design", OOPSLA '87 Conference Proceedings, ACM SIGPLAN Notices, Vol. 22, No. 12, 1987.
  5. Booch, Grady. "Object-Oriented Analysis and Design with Applications", Benjamin/Cummings, 1991. OOP 정의는 p.37, 객체 모델 4 major + 3 minor 요소는 2장 「The Object Model」.
  6. Booch 2장의 객체 모델 정리: 4 major elements는 Abstraction, Encapsulation, Modularity, Hierarchy. 3 minor elements는 Typing, Concurrency, Persistence.
  7. 통속적 3 pillars 정식의 대표적 형태. C++ 교육 자료에 빈번히 등장하나 단일 저자에 귀속되지 않는다.
  8. Armstrong, Joe. "Coders at Work: Reflections on the Craft of Programming", Peter Seibel 인터뷰, 2009.