2What — 절차형 코드란 무엇인가
3- 절차형(Procedural) 프로그래밍: 함수와 전역 변수를 중심으로, 위에서 아래로 흐르는 코드 구조
4- 데이터(변수)와 로직(함수)이 별도로 존재하며, 함수가 외부 상태를 직접 읽고 수정함
5- 100줄 이하의 작은 스크립트에서는 간결하고 직관적 → 빠르게 작성 가능
6Why — 코드가 커지면 절차형은 왜 무너지는가
7절차형 코드가 500줄 이상으로 성장할 때 반복적으로 나타나는 3가지 붕괴 패턴:
8- ① 전역 변수 얽힘 (Global State Entanglement)
9 - 예: 게임에서 player_hp, player_x, player_y, player_inventory 등 전역 변수 20개가 산재
10 - 어떤 함수가 player_hp를 바꿨는지 추적 불가 → 버그 원인 찾기가 탐정 수사 수준
11 - "스파게티 상태" — 하나를 바꾸면 예상 못 한 곳이 깨짐
12- ② 함수 간 암묵적 의존 (Implicit Dependencies)
13 - calculate_damage() 함수가 player_level, weapon_power, enemy_defense를 전역에서 읽음
14 - 함수 시그니처만 보면 의존 관계가 보이지 않음 → 리팩토링·테스트 시 공포 발생
15 - Brooks(1975)가 \textit{The Mythical Man-Month}에서 지적한 "소프트웨어 복잡성의 본질적 어려움"
16- ③ 데이터-로직 분리 (Data-Logic Separation)
17 - 은행 계좌 예: balance, owner, history는 딕셔너리, deposit(), withdraw(), get_statement()는 별도 함수
18 - 잘못된 함수가 balance를 직접 수정해도 막을 방법이 없음 → 데이터 무결성 붕괴
19 - 관련 데이터와 함수가 파일 곳곳에 흩어져 "이 데이터를 누가 쓰는가?"를 파악하려면 전체 검색 필요
20How — OOP는 이 문제를 어떻게 해결하는가
21- 핵심 원칙: 상태(데이터)와 행동(메서드)을 하나의 단위(객체)로 묶는다 (Encapsulation)
22- Kay(1993)의 정의: "OOP는 메시징, 캡슐화, 동적 바인딩이 핵심" — 객체끼리 메시지를 주고받는 구조
23- 절차형 → OOP 전환 비유
24 - 절차형 = 공용 주방: 모든 요리사가 같은 재료(전역 변수)를 공유 → 누가 소금을 넣었는지 모름
25 - OOP = 개인 조리대: 각 요리사(객체)가 자기 재료(속성)와 레시피(메서드)를 갖고, 완성된 요리만 전달
26- 실제 사용 사례 — "상태를 가진 사물"
27 - 게임 캐릭터: Character 객체가 hp, position, inventory를 내부에 보유 → 외부에서 직접 수정 불가, take_damage(amount) 메서드로만 변경
28 - 은행 계좌: Account 객체가 balance를 보호 → withdraw() 시 잔액 검증 로직이 객체 안에 포함
29 - API 클라이언트: APIClient 객체가 base_url, auth_token, session을 캡슐화 → 인증 상태를 자동 관리
30- OOP가 가져오는 구조적 이점
31 - 관련 변수 20개 → 객체 속성으로 그룹화 → 전역 네임스페이스 오염 제거
32 - 함수의 암묵적 의존 → 메서드의 명시적 self 참조로 전환 → 의존 관계가 코드에 드러남
33 - 데이터 무결성 → 메서드를 통해서만 상태 변경 → 불변 조건(invariant) 보장 가능
34 - Martin(2003)의 원칙: "좋은 설계는 변경의 영향 범위를 최소화한다" — 객체 경계가 바로 그 방화벽
35정리 — 언제 OOP가 필요한가
36- 상태가 있고, 그 상태를 조작하는 로직이 함께 있을 때 → OOP가 자연스러움
37- 상태 없이 입력→출력만 하는 변환 → 함수형이 더 적합할 수 있음
38- 핵심 판단 기준: "이 코드에 정체성을 가진 사물이 있는가?" → Yes면 클래스를 고려