본문으로 건너뛰기
객체는 무엇으로 이루어져 있는가

생성 수정

IBM * 레드햇 AX 과정 · 5강

객체는 무엇으로 이루어져 있는가

2026년 5월 11일(월) ~ 5월 15일(금)

이 강의 문제풀이 — 배운 내용을 주관식 문답으로 확인해보세요.풀어보기 →

이 장을 다 읽으면

  1. 객체·개체·함수를 각각 한 문장으로 정의하고, 셋이 무엇으로 갈리는지 말할 수 있다.
  2. 어떤 것이 디스크에 있고 어떤 것이 메모리에 있는지 구분할 수 있다.
  3. 필드와 메서드가 왜 서로 다른 메모리 영역에 저장되는지 설명할 수 있다.
  4. 코드 한 줄만 보고 두 객체가 연관관계인지 의존관계인지 판별할 수 있다.
  5. 동기와 비동기의 차이가 "속도"가 아니라 "기다림"임을 설명할 수 있다.
  6. 전략 패턴 하나로 DIP·IoC·DI·포트&어댑터를 한꺼번에 이해할 수 있다.
  7. 모노레포/멀티레포와 모놀리식/MSA가 서로 다른 축임을 안다.
  8. Neon(PostgreSQL)에 FastAPI를 비동기로 연결하고, 안 될 때 어디부터 볼지 안다.

0. 이 장의 판별 축

새 용어를 만나면 비유를 찾기 전에 아래 축 중 어디에 꽂히는지부터 정하세요. 비유부터 잡으면 경계가 흐려집니다. 축을 먼저 잡으면 아직 안 배운 것도 추론됩니다.

#축왼쪽 (0)오른쪽 (1)이 축으로 갈리는 것
1어디에 있는가디스크 (영구·정적)메모리 (휘발·동적)클래스 ↔ 인스턴스 / 프로젝트 ↔ 프로세스
2무엇을 가졌는가속성만 / 기능만속성 + 기능개체·함수 ↔ 객체
3누가 나눠 쓰는가모두 공유각자 하나씩메서드(공유) ↔ 필드(개별)
4기다리는가동기 (기다림)비동기 (안 기다림)Sync ↔ Async
5하나인가 여럿인가하나로 뭉침여럿으로 쪼갬모놀리식 ↔ MSA / 모노레포 ↔ 멀티레포

이 중 축 2가 이 장의 중심입니다. 이 축 하나로 객체·개체·함수가 한 번에 정리됩니다.


1. 객체 · 개체 · 함수 — 뺄셈으로 정의하기

1.1 정의

이 세 단어는 비유로 외우면 반드시 다시 헷갈립니다. 뺄셈으로 외우세요.

객체 (Object)   = 속성 + 기능
개체 (Entity)   = 객체 − 기능      →  저장만 된다
함수 (Function) = 객체 − 속성      →  변화만 일으킨다

정의를 유(類, 상위 범주) + 종차(種差, 그 안에서의 차이) 형식으로 쓰면 이렇게 됩니다.

  • 객체(Object) — [메모리에 존재하는 실체]인데, [속성과 기능을 모두 가진다]는 점에서 개체·함수와 구별된다.
  • 개체(Entity) — [데이터의 단위]인데, [속성만 있고 기능이 없다]는 점에서 객체와 구별된다.
  • 함수(Function) — [실행되는 코드]인데, [기능만 있고 상태를 보관하지 않는다]는 점에서 객체와 구별된다.
  • 메서드(Method) — [함수]인데, [특정 객체에 소속되어 그 객체의 속성을 재료로 쓴다]는 점에서 일반 함수와 구별된다.

1.2 좌표평면으로 보기

                    기능 있음                기능 없음
                 ┌──────────────────┬──────────────────┐
    속성 있음     │   객체 (Object)   │   개체 (Entity)   │
                 │   메모리·RAM      │   DB·디스크       │
                 ├──────────────────┼──────────────────┤
    속성 없음     │  함수 (Function)  │   (성립 안 함)     │
                 │   화면·UI         │                  │
                 └──────────────────┴──────────────────┘

네 칸 중 세 칸만 존재합니다. 속성도 기능도 없는 것은 아무것도 아니기 때문입니다.

1.3 각 칸이 실제로 어디에 있는가

이 세 칸은 관념이 아닙니다. 우리가 만드는 시스템의 실제 물리적 위치와 일대일로 대응됩니다.

칸약자실제 위치기술하는 일
개체D (data)데이터베이스PostgreSQL 테이블저장만
객체M (model)백엔드 메모리Python 클래스저장 + 변화
함수V (view)브라우저React 컴포넌트화면 변화
함수C (control)백엔드 진입부FastAPI 라우터요청 전달

D-M-V-C. 흔히 말하는 MVC에 D(개체) 를 앞에 붙인 형태입니다. MVC만 배우면 "Model이 DB인가 객체인가"가 계속 헷갈리는데, D를 따로 세우면 그 혼란이 사라집니다.

  • Model = 메모리 위의 객체 (기능이 있다)
  • Data = DB 안의 개체 (기능이 없다)

1.4 왜 한국어로 배우면 헷갈리는가

"개체"와 "객체"는 발음이 거의 같습니다. 그래서 한국어로만 배우면 같은 말의 오타처럼 느껴집니다.

영어로는 완전히 다른 단어입니다.

한국어영어어원
객체Objectob-(향하여) + jacere(던지다) → 던져진 것, 다루어지는 대상
개체Entityesse(있다) → 존재하는 것 자체

Object는 행위의 대상이고, Entity는 존재의 단위입니다. 그래서 DB 설계에서는 Entity라는 말을 쓰고(존재하는 대상을 정의하는 일), 프로그래밍에서는 Object라는 말을 씁니다(코드가 다루는 대상).

주체(Subject)와의 대비 Object의 반대말은 Subject(주체)입니다. Subject는 행위를 하는 쪽(사용자, 실행 중인 프로그램), Object는 행위를 당하는 쪽(다루어지는 데이터, 조작되는 파일)입니다. 다만 일반적인 객체지향에서 '오브젝트'는 이 주체/객체 대비보다는 '독립된 실체' 자체를 뜻합니다.

1.5 터미널과 브라우저 — 개체가 객체가 되는 순간

이 장에서 가장 오래 남는 통찰입니다.

  • 터미널은 객체화되지 않은 개체(글자) 를 날것 그대로 보는 곳입니다.
  • 브라우저는 데이터가 객체화되어야만 서비스로서 문이 열리는 공간입니다.

프로그래밍이란 결국,

터미널 속 죽어 있는 글자(개체)에 함수를 부여해 메서드를 만들고, 이를 메모리상에 객체로 부활시켜 브라우저에서 서비스로 열어주는 과정

입니다. SQL은 이 과정에서 터미널에 갇힌 개체들을 꺼내 객체화의 재료로 운반하는 역할을 합니다.


2. 디스크와 메모리 — 모든 것은 둘 중 하나에 있다

2.1 두 세계

디스크 (Disk)메모리 (Memory / RAM)
성격영구 저장임시 저장
전원이 꺼지면남는다사라진다
속도느림매우 빠름
용량큼작음
비유창고작업대

컴퓨터의 거의 모든 개념이 이 두 세계 중 하나에 속합니다. 어느 쪽인지 정하는 것만으로 절반은 이해됩니다.

2.2 클래스와 인스턴스

  • 클래스(Class) — 디스크에 .py 파일로 저장된 설계도(Blueprint). 프로그램이 실행되지 않아도 존재합니다.
  • 인스턴스(Instance) — 실행 시 그 설계도를 읽어 메모리(RAM)에 세운 실체. 프로그램이 끝나면 사라집니다.

영어권에서 자주 쓰는 세 가지 비유입니다.

비유클래스인스턴스
Blueprint & House설계도실제로 지어진 집
Cookie Cutter & Cookies쿠키 틀찍어낸 쿠키들
Car Design & Actual Car자동차 도면도로를 달리는 실제 차

"클래스 + 인스턴스 = 오브젝트" 라는 설명도 있습니다. "능력(클래스/정의)"이 "몸체(인스턴스/메모리)"를 얻어 실제로 살아 움직이는 완성체(객체)가 된다는 역동적인 관점입니다.

객체(Object)와 인스턴스(Instance)는 같은 대상을 가리키지만 관점이 다릅니다.

  • 객체: 독립적인 물건 그 자체를 부를 때 — "저기 데이터 덩어리가 있네"
  • 인스턴스: 어떤 설계도에서 태어났는지 소속을 강조할 때 — "저건 Walter 클래스의 인스턴스야"

2.3 4P — 프로덕트·프로젝트·프로그램·프로세스

같은 축으로 네 단어가 정리됩니다.

구분위치성격정의비유
프로덕트 (Product)디스크결과 / 보관고객에게 최종 전달되어 가치를 창출하는 완성된 결과물창고 안의 완제품
프로젝트 (Project)디스크계획 / 자산프로덕트를 만들거나 개선하기 위해 한시적으로 투입되는 자원과 계획의 집합창고 안의 작업 재료함
프로그램 (Program)메모리준비 / 대기목적을 위해 메모리에 로드되어 실행 대기 중인 명령어 집합작업대 위 펼쳐진 매뉴얼
프로세스 (Process)메모리실행 / 활동메모리 안에서 실제로 CPU 자원을 쓰며 명령을 수행 중인 실행 인스턴스작업대 위 실제 손놀림

프로젝트에는 기획서, 소스 코드, 일정표 등 실행되기 전의 기록물이 들어갑니다. 프로세스는 프로그램이 실제 데이터(사내 규정, 고객 정보 등)를 처리하며 결과를 도출하는 역동적인 과정입니다.

여기에 두 단어를 더 붙일 수 있습니다.

  • 런타임(Runtime) — 프로그램이 실제로 실행되고 있는 시간과 그 환경 (경기 진행 중)
  • 스레드(Thread) — 프로세스 안에서 실제로 코드를 실행하는 일꾼 (경기장을 뛰는 선수)

2.4 오가는 방향에는 이름이 있다

방향이름다른 이름뜻
메모리 → 디스크SAVE직렬화 (Serialization)실행 중인 상태를 기록함
디스크 → 메모리LOAD역직렬화 (Deserialization)저장된 기록을 부활시킴

직렬화(Serialization) 는 메모리 위의 입체적인 객체를 디스크에 저장하기 위해 일렬로 늘어뜨리는 과정입니다. AI 모델을 파일로 저장하고 나중에 다시 불러올 수 있는 것도 이 덕분입니다.

⚠️ 업로드/다운로드와 헷갈리지 마세요. SAVE/LOAD는 내 컴퓨터 안의 디스크↔메모리 이동입니다. 업로드/다운로드는 인터넷 너머 남의 서버와 주고받는 것입니다. 축이 다릅니다.

2.5 객체가 저장소에 도달하기까지 4단계

객체(Object) ──(추출/변환)──▶ 데이터(Data/DTO) ──(전달)──▶ 레포지토리(Repository) ──(기록)──▶ 저장소(Storage/DB)
  1. 객체 (The Object) — 프로그램 실행 중 메모리에 살아있는 실체. 데이터(Value)와 기능(Method)을 함께 가짐. 휘발성.
  2. 데이터화 (DTO) — 복잡한 객체에서 순수한 값만 뽑아 전송 가능한 형태로 변환.
    • 비결합: 객체의 복잡한 기능을 제거하고 데이터만 남김
    • 표준화: 주로 딕셔너리나 JSON 같은 표준 구조를 갖게 됨
    • 복잡한 기계(객체)를 운반하기 쉽게 부품별로 상자에 담는 과정입니다.
  3. 레포지토리 (Repository) — 데이터를 저장·관리하는 논리적 관리자(창고지기).
    • 중재: 비즈니스 로직과 실제 저장 기술(DB, 파일 등) 사이를 연결
    • 추상화: "어떻게 저장할지"의 복잡한 로직을 숨기고 "저장해줘"라는 단순한 인터페이스만 제공
    • 덕분에 저장 방식이 엑셀 → 데이터베이스로 바뀌어도 프로그램 전체를 수정할 필요가 없습니다.
  4. 영속성 및 저장소 (Persistence & Storage) — 하드디스크·DB·클라우드에 영구 보관. 프로그램이 재시작되어도 다시 불러와 객체로 복원 가능.

코드가 사는 곳과 데이터가 사는 곳도 다릅니다. 코드가 저장된 곳은 repository, 데이터가 저장된 곳은 data center(대규모) 또는 data mart(소규모)입니다.

2.6 메모리 3영역 — 누가 나눠 쓰는가

메모리는 한 덩어리가 아닙니다. 누가 나눠 쓰느냐에 따라 세 구역으로 나뉩니다.

영역무엇이 들어가나공유하는가언제 사라지나
Method Area클래스 정보, 메서드 코드, 클래스 변수✅ 모든 인스턴스·모든 스레드가 공유프로그램 종료 시
Heap Areaself 로 만들어진 인스턴스, 인스턴스 변수⚠️ 참조하는 쪽끼리만참조가 끊기면 GC가 수거
Stack Area지역 변수, 매개변수, 호출 정보❌ 스레드마다 각자메서드가 끝나면 즉시

왜 이렇게 나눴는가 — 메모리 절약 때문입니다.

인스턴스를 1,000개 만든다고 합시다.

  • 필드(각 스마트폰의 배터리 잔량)는 1,000개가 각각 달라야 합니다 → Heap
  • 메서드(전화 거는 방법)는 1,000개가 전부 똑같습니다 → 하나만 두고 공유 → Method Area

만약 메서드도 인스턴스마다 복사했다면 메모리가 1,000배로 늘어납니다.

2.7 필드와 메서드

필드 (Field)메서드 (Method)
무엇인가클래스 안의 변수클래스 안의 함수
답하는 질문객체가 무엇을 알고 있는가 (What it knows)객체가 무엇을 할 수 있는가 (What it does)
예각 스마트폰의 배터리 잔량스마트폰의 통화 기능
메모리인스턴스마다 독립 (Heap)모두가 공유 (Method Area)

필드는 다시 두 종류로 갈립니다.

클래스 변수 (Class Field)인스턴스 변수 (Instance Field)
언제 만들어지나프로그램 실행 시 디스크에서 Method Area로 로드실행 중(Runtime) Heap에 동적 생성
성격모든 객체가 공유하는 정적(Static) 설계도·규칙개별 객체가 독립적으로 갖는 살아 움직이는 데이터

Field와 Area는 다른 말입니다. Field는 논리적·추상적 경계(학문 분야, 데이터 칸)를 뜻하고, Area는 물리적·가시적 경계(구역, 면적)를 뜻합니다. 축구(Soccer)는 탁 트인 들판(Field) 에서의 활동을 강조하고, 아이스하키(Hockey)는 구획된 얼음판(Rink/Area) 을 강조합니다.

그래서 필드 에어리어는 객체가 살아있는 동안 유지되는 전역적 범위이고, 로컬 에어리어는 메서드 실행 시 잠깐 생겼다 사라지는 임시 작업대(지역 변수)입니다.

2.8 스레드와 메모리

스레드(Thread) 는 프로세스 안에서 실제로 코드를 실행하는 최소 단위입니다. 메모리에 올라온 메서드가 런타임에 활성화되어 실행되는 흐름 — 그게 스레드입니다.

[Method Area]  ← 모든 스레드가 같이 봄 (코드·클래스변수)
      ↑ 실행
스레드1 [Stack1]   스레드2 [Stack2]   스레드3 [Stack3]   ← 각자 따로
      ↓ 참조
[Heap]  ← 객체들이 사는 곳. 여러 스레드가 같은 객체를 볼 수 있음
  • 모든 스레드는 Method Area를 공유합니다 (같은 코드를 봅니다).
  • 하지만 Stack은 각자 가집니다. 그래서 여러 스레드가 같은 메서드를 동시에 실행해도 지역 변수는 서로 안 섞입니다.
  • 반면 Heap의 객체는 공유될 수 있습니다. 여기서 동시성 문제가 생깁니다.

비유로 정리하면: 레시피(String, 데이터)를 보고 실제로 요리를 하는 요리사가 스레드입니다.

2.9 프로그래밍 파일의 구조

파이썬 파일 하나는 대개 이렇게 층이 나뉩니다.

# [1-1] 임포트 영역 (Import Area)
from pathlib import Path
import pandas as pd

# [1-2] 상수 및 전역 설정 (Global Constants)
_DATA_DIR = ...
_CSV_PATH = ...

# [2] 클래스 정의 영역 (Class Definition Area)
class WalterReader:
    def __init__(self):        # 초기화 메서드 — 객체 생성 시 실행되는 초기 설정
        ...
    def get_data(self):        # 인스턴스 메서드 — 실제 기능
        ...
  • 임포트 영역: 외부 라이브러리나 모듈을 현재 스크립트로 불러오는 단계
  • 상수 및 전역 설정: 프로그램 전체에서 공유되는 고정값. 보통 대문자와 언더바(_)를 섞어 명명하며 파일 경로 등을 설정
  • 클래스 정의 영역: 객체의 데이터와 동작을 설계하는 곳

⚠️ 용어 주의: 이 아래쪽 영역을 "클래스 필드"라고 부르면 틀립니다. 필드는 클래스 내부의 변수이고, 대부분의 내용이 메서드(함수) 라면 '클래스 정의 영역' 또는 '메서드 정의 영역' 이라고 부르는 게 정확합니다.

성능 관련 조언: 각 메서드가 실행될 때마다 CSV를 다시 읽는 구조는 데이터가 클 때 성능 저하를 부릅니다. __init__에서 한 번 로드해 self.df 형태로 들고 있는 것이 권장 패턴입니다.


3. 객체와 객체의 관계

3.1 관계는 딱 세 종류뿐이다

두 객체 사이에 존재할 수 있는 관계는 셋뿐입니다. 서구 분류학이 소프트웨어에 그대로 들어온 자리입니다.

관계영어뜻예
상속IS-A~는 ~의 한 종류다개는 동물이다
연관HAS-A~는 ~를 가지고 있다자동차는 엔진을 가진다
의존USES-A~는 ~를 잠시 쓴다운전자는 자동차를 쓴다

3.2 코드 위치가 곧 관계다

연관과 의존은 인스턴스를 만드는 코드가 어디에 있는지만 보면 판별됩니다.

class OrderService:
    def __init__(self):
        self.repo = OrderRepository()   # ← 연관관계 (Association / HAS-A)
        # 객체가 살아있는 동안 self.repo 도 계속 살아있다

    def send_mail(self):
        mailer = Mailer()               # ← 의존관계 (Dependency / USES-A)
        mailer.send()
        # 메서드가 끝나면 mailer 는 사라진다
연관관계 (Association)의존관계 (Dependency)
코드 위치__init__ (생성자) 안일반 메서드 안
저장 위치Heap (인스턴스 필드로)Stack (지역 변수로)
수명객체와 함께 삶메서드 끝나면 소멸
UML 표기실선 ──점선 ⇢
영어HAS-AUSES-A
비유내 주머니 속의 스마트폰주문할 때만 만나는 배달 기사

둘 중 무엇이 좋고 나쁜 것이 아닙니다. 둘을 얼마나 효율적으로 쓰느냐가 성능을 결정합니다. 자주 쓰는 것을 매번 새로 만들면 낭비이고, 한 번만 쓰는 것을 계속 들고 있으면 메모리 낭비입니다.

앞으로 다시 만납니다 이 실선/점선 구분은 데이터베이스 설계의 식별 관계 / 비식별 관계 와 정확히 대응됩니다. 실선은 실선끼리, 점선은 점선끼리 만납니다. 우연이 아닙니다 — 둘 다 "이것 없이 저것이 존재할 수 있는가" 라는 같은 질문을 묻고 있기 때문입니다.


4. 기다림의 문제 — 동기와 비동기

4.1 정의

동기 (Synchronous)비동기 (Asynchronous)
정의앞선 작업이 완전히 끝나야 다음 작업을 시작요청한 뒤 완료를 기다리지 않고 다음 일을 함
다른 이름Blocking (대기)Non-blocking (알림)
처리직렬 처리병렬 처리 효과
제어간단하지만 비효율적복잡하지만 응답성이 높음
비유카페에서 커피가 나올 때까지 카운터 앞에서 기다림진동벨을 받고 자리에 앉아 다른 일을 하다가 벨이 울리면 받으러 감

4.2 인터넷의 역사가 그대로 이 축이다

모뎀 시대 (동기)

모뎀 연결(다이얼링음) → 요청 전송(HTML 가져오기) → 전체 응답 대기(로딩바) → 텍스트 수신 후 이미지 요청

한 번에 하나씩. 전화 통화처럼 한 명이 회선을 점유합니다.

현대 인터넷 (비동기)

초광대역 연결 → 다중 요청 전송(텍스트·이미지·댓글·광고) → 도착하는 순서대로 각각 렌더링

멀티태스킹 메신저처럼, 보내놓고 다른 일을 하다가 답이 오면 처리합니다.

4.3 흔한 오해 — 비동기는 "빠른 것"이 아니다

한 건의 처리 시간은 동기든 비동기든 똑같습니다. 기다리는 동안 다른 일을 할 수 있어서 전체 처리량이 늘어나는 것입니다.

그래서 비동기가 도움이 되는 곳이 정해져 있습니다.

작업 종류비동기가 도움이 되나이유
I/O 대기 — DB 조회, API 호출, 파일 읽기✅ 크게 도움대부분의 시간이 기다리는 시간
CPU 계산 — 이미지 처리, 대규모 연산❌ 도움 안 됨기다리는 게 아니라 실제로 일하는 중

나중에 Neon DB에 연결할 때 굳이 create_async_engine, AsyncSession 을 쓰는 이유가 이것입니다. DB 조회는 전형적인 I/O 대기이고, Neon은 싱가포르 리전에 있어 네트워크 왕복 시간이 큽니다.

4.4 옆에 있는 다른 축 — 부모/자식/형제

동기·비동기와 자주 같이 나오지만 완전히 다른 축이 있습니다.

구분부모-자식 / 시블링동기 / 비동기
핵심 키워드구조 (Structure)시간 (Time / Flow)
관심사누가 누구를 포함하는가?작업을 기다리는가, 마이웨이인가?
비유가계도, 폴더 구조진동벨 시스템, 줄서기
  • 부모(Parent): 상위 계층 요소. 하위 요소를 감싸거나 제어. 방향은 수직
  • 자식(Child): 부모에게 속한 하위 요소. 부모의 속성을 물려받기도 함
  • 시블링(Sibling, 형제): 같은 부모를 둔 동등한 레벨의 요소들. 방향은 수평. 서열 없이 '이전/다음' 순서만 존재

5. 패턴 — 반복되는 해법에 이름 붙이기

5.1 패턴은 추상, 아키텍처는 구상

이 한 줄이 이 장에서 가장 실용적인 구분입니다.

패턴 (Pattern)아키텍처 (Architecture)
무엇인가반복되는 문제의 해결 방식이 시스템의 실제 구조
존재 형태머릿속·책 속 (구현이 아님)폴더·파일·서버로 존재
개수한 시스템에 여러 개를 동시에 씀한 시스템에 하나
말할 때"여기 전략 패턴 쓰자""우리는 모듈러 모놀리식이야"

아키텍처(Architecture)와 아키텍트(Architect) 도 같이 구분해 둡시다.

아키텍처 (Architecture)아키텍트 (Architect)
무엇시스템의 전체 구조와 동작 원리를 정의한 설계 청사진비즈니스 요구사항을 기술적 해결책으로 변환하는 설계자
내용컴포넌트 간 상호작용, 데이터 흐름, 기술적 의사결정의 집합기술적 리더십, 장단점 분석, 트레이드오프 결정
가치성능·보안·확장성 등 비기능 요구사항 충족, 시스템 안정성 보장복잡성 해결, 소통, 가이드 제공

영어 어미가 이미 구분해 놓았습니다. -ure는 결과물, -ect는 사람입니다. architecture(구조물) ↔ architect(설계자), sculpture(조각품) ↔ sculptor(조각가). 한국어로는 둘 다 "설계"로 뭉뚱그려지지만, 영어는 결과물과 그것을 만드는 사람을 다른 범주로 봅니다.

5.2 전략의 세 층위

패턴은 크기에 따라 세 층으로 나뉩니다. 하위 전략은 상위 전략 안에서 작동합니다.

층위이름다루는 범위예
소전략GoF 디자인 패턴객체 수준의 코드 재사용·확장Singleton, Strategy, Observer, Factory
중전략아키텍처 패턴서브시스템 상호작용, 관심사 분리MVC, MVP, MVVM, 클린 아키텍처
대전략시스템 아키텍처거시 구조, 가용성·확장성, 배포 전략MSA, 모놀리식, 서버리스

전략(Strategy)과 전술(Tactics) 도 같은 층위 감각입니다.

  • 전략: "무엇을 할 것인가" — 장기적·거시적 계획. 방향성을 결정하며 변경이 어렵다. 승리(Goal) 를 설계
  • 전술: "어떻게 할 것인가" — 단기적·미시적 행동 지침. 상황에 따라 유연하게 변경. 전투(Task) 를 수행

프레임워크가 "전략"인 이유도 여기서 나옵니다. 프레임워크는 소프트웨어를 개발하기 위한 표준화된 뼈대입니다. 제어의 역전(IoC) 이 일어나서, 개발자는 규칙에 따라 코드만 채워 넣습니다. 개인의 역량 차이를 극복하고 조직 전체의 생산성과 보안 수준을 상향 평준화하는 시스템적 전략이기 때문에 전략입니다.

5.3 GoF 23패턴 — 무엇을 기준으로 나뉘는가

GoF(Gang of Four) 패턴은 무엇을 조작하느냐를 기준으로 셋으로 나뉩니다.

분류언제 쓰는가패턴
생성 (Creational)객체를 만드는 행위Abstract Factory, Builder, Factory Method, Prototype, Singleton
구조 (Structural)객체가 개체로 바뀔 때 구조 변경Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy
행위 (Behavioral)객체↔함수 간 행위 변경Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor

기억할 만한 것들만 뽑으면:

패턴분류한 줄
싱글톤생성인스턴스를 오직 하나만 생성하도록 보장
팩토리 메서드생성객체 생성을 서브클래스에서 결정하도록 위임
빌더생성복잡한 객체의 생성 단계와 표현 단계를 분리
어댑터구조호환되지 않는 인터페이스를 연결
데코레이터구조객체에 동적으로 새 기능을 추가
프록시구조다른 객체에 대한 접근을 제어하는 대리자
전략행위알고리즘을 캡슐화해 실행 중 교체 가능하게 함
옵저버행위상태 변화를 의존 객체들에 통지
템플릿 메서드행위알고리즘 골격을 정의하고 일부 단계를 서브클래스에서 구현

5.4 전략 패턴이 "GoF의 꽃"인 이유

정의: 전략 패턴은 [행위 패턴]인데, [알고리즘 여러 개를 각각 클래스로 만들어 실행 중에 갈아끼울 수 있게 한다]는 점에서 다른 행위 패턴과 구별된다.

Strategy is a behavioral design pattern that lets you define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.

왜 나머지 22개보다 중요한가 — 다른 개념들이 전부 이것의 다른 이름이기 때문입니다.

이름어느 맥락에서 부르는 이름인가
전략 패턴 (Strategy)디자인 패턴 맥락
DIP (의존성 역전 원칙)SOLID 원칙 맥락
IoC (제어의 역전)프레임워크 맥락
DI (의존성 주입)실제 구현 기법 맥락
포트 & 어댑터헥사고날 아키텍처 맥락

다섯이 전부 같은 한 가지를 말합니다.

"쓰는 쪽은 인터페이스만 알고, 실제 물건은 밖에서 넣어준다."

쓰는 쪽 ──▶ [인터페이스(Port)] ◀── 실제 구현(Adapter)
             ↑ 화살표가 이렇게 마주보는 게 "역전(Inversion)"

세 가지 이유로 꽃입니다.

  1. 유연성 — 런타임에 전략 교체가 가능
  2. 상속 대신 조합 — OCP(개방-폐쇄 원칙) 준수
  3. DI와의 연관성 — 현대 애플리케이션의 유연한 구조의 핵심

골프백에 여러 클럽이 꽂혀 있는 그림이 이 패턴의 대표 삽화입니다. 교체 가능한 전략들의 모음입니다.

참고로 멀티스레드 환경에서는 "생산자-소비자 패턴"이 핵심으로 꼽히기도 합니다.

5.5 싱글톤 — 하나만 있어야 하는 것들

정의: 싱글톤은 [생성 패턴]인데, [그 클래스의 인스턴스가 프로그램 전체에 딱 하나만 존재하도록 강제한다]는 점에서 다른 생성 패턴과 구별된다.

API 키 관리가 싱글톤의 교과서적 사례입니다. 세 조건이 전부 맞습니다.

싱글톤이 맞는 조건키 관리가 만족하는가
여러 개 있으면 안 되는 것✅ 키를 읽는 곳이 여러 개면 유출 지점도 여러 개
만드는 비용이 비싼 것✅ .env 읽기·검증을 매번 할 이유가 없음
상태를 공유해야 하는 것✅ 키가 갱신되면 전체가 같이 바뀌어야 함
class Keymaker:
    _instance = None                  # 클래스 변수 (Method Area, 모두가 공유)

    @classmethod
    def instance(cls):
        if cls._instance is None:     # 없을 때만 만든다
            cls._instance = cls()
        return cls._instance          # 항상 같은 객체를 돌려준다

def get_keymaker():                   # 팩토리/헬퍼 — 부르는 쪽을 편하게
    return Keymaker.instance()

def reset_instance():                 # 테스트용 — 테스트끼리 상태가 새지 않게
    Keymaker._instance = None

_instance 가 클래스 변수라는 게 핵심입니다. 앞에서 배운 "클래스 변수는 Method Area에 있고 모든 인스턴스가 공유한다" 가 여기서 그대로 쓰입니다. 공유되기 때문에 "이미 만들어졌는가"를 모두가 같은 답으로 알 수 있습니다.

⚠️ 싱글톤의 그림자 싱글톤은 사실상 전역 변수입니다. 남용하면 ① 테스트가 어려워지고(상태가 테스트 간에 샘) ② 의존성이 코드에 숨습니다. reset_instance() 가 붙어 있는 이유가 ①번 때문입니다. 현대 코드에서는 싱글톤 대신 DI 컨테이너로 "하나만 만들어서 주입" 하는 쪽을 더 선호합니다.

5.6 어댑터 패턴 — DB를 연결하는 4단계

목표: 도메인(핵심 로직)이 어떤 DB를 쓰는지 전혀 모르게 만드는 것.

단계구성 요소역할위치
1Port도메인이 필요한 데이터 작업을 정의한 인터페이스Domain
2Adapter특정 DB 기술로 Port를 실제 구현Infrastructure
3Mapper도메인 객체 ↔ DB 엔티티 변환Infrastructure
4DI서비스가 포트를 호출할 때 어댑터를 연결Configuration

1단계: 출력 포트(Output Port) 정의 도메인 계층에 인터페이스를 만듭니다. 위치는 Domain/Hexagon Core. 외부 라이브러리(JPA, MyBatis, SQLAlchemy 등) 의존성이 전혀 없는 순수 인터페이스여야 합니다.

2단계: 영속성 어댑터(Persistence Adapter) 구현 Infrastructure 계층에서 그 포트를 실제로 구현합니다. 여기서 실제 DB 기술을 씁니다. 역할은 도메인 언어를 DB 언어로 번역하는 것입니다.

3단계: 데이터 매핑 도메인 객체(Order)와 DB 테이블 객체(OrderEntity)를 엄격히 분리하고 어댑터 안에서 변환합니다. DB 컬럼명이 바뀌어도 도메인 로직이 깨지지 않게 하기 위함입니다.

4단계: 의존성 주입

Service(Use Case) ──▶ OrderRepositoryPort(Interface) ◀── OrderPersistenceAdapter(Implementation)

⚠️ "영속성 전이"를 막아야 합니다. DB 엔티티(@Entity 등)를 도메인 계층까지 끌고 들어오면 이 구조를 쓰는 의미가 없어집니다. 번거롭더라도 도메인 모델과 DB 모델을 별도로 관리하세요.

5.7 처음 시작할 때 필요한 패턴 4가지

MSA로 거시구조를 잡고 미시구조로 헥사고날 + 클린 + DDD를 구성할 때, 처음 필요한 패턴은 넷입니다.

  1. 전략 패턴(Strategy) — "제어의 역전(IoC)과 의존성 역전(DIP)의 실현"
    • 도메인에서 인터페이스(Port)를 정의하고 실제 구현체(Adapter)는 런타임에 주입
    • DB를 MySQL → MongoDB로 바꾸거나 결제 모듈을 바꿔도 도메인 코드는 한 줄도 수정 불필요
  2. 팩토리 패턴(Factory) — "복잡한 도메인 객체 생성의 캡슐화"
    • 여러 엔티티가 결합된 애그리거트를 유효성 검사 포함해 '완전한 상태'로 반환
  3. CQRS — "읽기와 쓰기의 모델 분리"
    • Command는 도메인 로직·트랜잭션 / Query는 DTO로 바로 변환해 성능 최적화
    • 복잡한 도메인 모델이 조회 기능 때문에 오염되는 것을 방지
  4. 데이터 매퍼 / DTO — "계층 간 결합도 해제"
    • Persistence Mapper는 DB 엔티티 ↔ 도메인 엔티티
    • DTO는 외부 API 요청/응답 ↔ Use Case 모델

💡 처음부터 다 하지 마세요. 전부 한꺼번에 적용하면 "보일러플레이트 지옥" 이 됩니다. 우선순위는 ① Port/Adapter(전략 패턴) 인터페이스 분리 → ② Entity vs DTO 분리 입니다. CQRS는 조회 성능이 중요한 곳에만 가볍게 적용하세요.

5.8 앞으로 쓸 3대 아키텍처

이 주에 이름만 나오고, 6주차부터 본격적으로 다룹니다.

헥사고날 아키텍처 (Hexagonal Architecture)

  • 비즈니스 로직을 중심(Core)에 두고, 외부 시스템(DB·UI·API)을 어댑터를 통해 연결하는 '포트와 어댑터' 패턴
  • 목적: 내부 도메인이 특정 기술 스택에 종속되지 않는 '기술적 불가지론' 을 실현

클린 아키텍처 (Clean Architecture)

  • 시스템을 여러 동심원 계층으로 분리하고, 모든 의존성이 고수준 비즈니스 규칙(안쪽)으로만 향하게 하는 '의존성 규칙'
  • 목적: 프레임워크·외부 도구의 변경으로부터 비즈니스 로직을 독립시켜 테스트 가능성과 수명을 높임

도메인 주도 설계 (DDD)

  • 기술적 복잡성보다 비즈니스 도메인의 복잡성에 집중. 보편적 언어(Ubiquitous Language) 로 소프트웨어 모델과 비즈니스 개념을 일치
  • 목적: Bounded Context 를 통해 대규모 시스템의 책임을 명확히 분리

이때 쓰이는 전략적 패턴들

패턴역할이점
어댑터외부 인터페이스를 내부 포트 표준으로 변환내부 도메인과 외부 인프라 간 물리적 결합 제거
빌더복잡한 객체 생성 과정의 캡슐화 및 유효성 강제생성 시점부터 객체의 비즈니스 무결성 보장
매퍼계층별 전용 데이터 모델 간 상호 변환한 계층의 모델 변경이 다른 계층으로 전파되는 것을 차단
전략유사 행위들을 런타임 교체 가능한 알고리즘군으로 정의정책 변화·확장에 대해 OCP 실현
값 객체 (VO)식별자가 아닌 속성값 조합으로 정의되는 불변 객체도메인 로직 응집도 상승, 부수 효과 방지

5.9 절차지향에서 객체지향으로

절차지향 (Procedural)객체지향 (Object-Oriented)
특징순차적 명령어 실행 중심. 데이터와 함수가 분리데이터와 함수를 하나로 묶은 '객체' 간의 상호작용
도구—캡슐화, 상속, 다형성
비유한 장의 긴 요리 레시피역할이 나뉜 주방

객체지향이 나온 이유는 셋입니다.

  1. 복잡성 관리 — 거대해진 소프트웨어를 부품 단위로 관리 가능
  2. 재사용성 — 잘 만든 객체를 다른 프로젝트에서 재사용
  3. 유지보수 — 특정 부품(객체)만 수정하면 되므로 변화에 유연

캡슐화(Encapsulation) 가 이 셋을 가능하게 하는 장치입니다. 관련 있는 데이터(속성)와 그 데이터를 처리하는 도구(기능)를 하나로 묶는 것 — 그래서 속성과 기능을 나누어 생각하되 한 곳에 둡니다.


6. 구조를 어떻게 나눌 것인가

6.1 섞이기 쉬운 두 개의 질문

여기서 초보자가 가장 많이 헷갈립니다. 완전히 다른 두 질문이 비슷한 단어로 불립니다.

질문축의 이름선택지
코드를 어디에 보관하나저장소 축모노레포 ↔ 멀티레포
서버를 어떻게 띄우나배포 축모놀리식 ↔ MSA

두 축은 독립적입니다. 네 조합이 전부 가능합니다.

모놀리식 배포MSA 배포
모노레포가장 단순 (초기)구글·메타 방식
멀티레포드묾전통적 MSA

6.2 모노레포 vs 멀티레포 — AI 시대의 판단 기준

구분모노레포 (Monorepo)멀티레포 (Multirepo)
구조하나의 저장소에 모든 프로젝트프로젝트당 개별 저장소
AI 접근성전체 코드의 맥락을 한눈에 파악저장소 간 단절로 전체 흐름 이해 부족
분석 효율함수 호출, 데이터 모델 공유 파악 용이다른 저장소 코드를 참조하기 번거로움
권장 상황1인/소규모 팀, AI 활용 극대화 시대규모 조직, 팀별 독립 권한 관리 시

AI 코딩 도구(Cursor, Copilot 등)를 쓰는 관점에서 차이는 이렇게 갈립니다.

모노레포 (AI 최적화)

  • FULL CONTEXT VISIBILITY — AI가 전체 코드베이스를 보고 이해할 수 있음
  • EFFICIENT KNOWLEDGE RAG — 모든 모듈을 가로질러 검색 가능
  • IMPACT ANALYSIS — 모듈 간 부수 효과를 AI가 감지

멀티레포 (파편화 문제)

  • FRAGMENTED CONTEXT — AI가 시스템 전체 지식을 갖지 못함
  • LIMITED RAG SCOPE — 검색이 한 저장소 안으로 제한됨
  • HIDDEN DEPENDENCIES — 저장소를 넘나드는 변경을 추적하기 어려움

결론: AI가 쓰기엔 멀티레포가 어렵습니다.

6.3 모듈러 모놀리식 — MSA로 갈 준비를 해둔 채 시작하기

'요리사 한 명인 식당' 비유로 봅시다.

MSA (마이크로서비스 아키텍처)

  • 기능을 건물 단위로 쪼개어 각각 별도의 서버로 운영
  • 관리 관점: 10개의 독립된 건물을 관리하는 것과 같음. 건물마다 전기·수도·보안을 따로 설정 → 물리적 관리 포인트가 매우 많음
  • 단점: 소규모 팀에서는 서버 비용과 네트워크 통신 오류 관리에 에너지를 다 씀

모듈러 모놀리식 (Modular Monolith)

  • 하나의 큰 빌딩 안에 살되, 내부적으로 명확한 벽과 문(모듈)을 세워 구역을 나눔
  • 관리 관점: 건물은 하나이므로 전기·보안 시스템은 1개만 관리. 대신 내부 방(모듈)의 용도만 구분
  • 장점: 물리적 관리는 단순화하면서 코드의 논리적 독립성은 유지
MSA모듈러 모놀리식
물리적 관리 포인트서비스 수만큼1개
서비스 간 통신네트워크 (택배) — 느리고 실패 가능메모리 호출 (직접 전달)
논리적 독립성✅✅ (모듈 경계로)
나중에 쪼개기—모듈 단위로 떼어내면 됨
AI 활용❌ 맥락 파편화✅ 전체 맥락

왜 관리에 더 유리한가 — 세 가지 이유

  1. 인프라 단순화 (그릇의 통합) — 서버 설정, 보안 패치, 모니터링을 10번 할 것을 1번으로
  2. 소통 비용 절감 (직접 전달) — 데이터 전달 시 '택배(네트워크)'를 부를 필요 없이 복도에서 '직접 전달(메모리 호출)'. 오류가 적고 빠름
  3. AI 시너지 — AI는 파편화된 정보보다 한곳에 모인 정보를 분석할 때 훨씬 정확한 코드를 제안

1인/소규모 개발자의 실행 전략

  1. 시작은 모노레포 — 모든 소스코드를 한 저장소에 넣어 AI가 비즈니스 전체를 학습하게
  2. 설계는 모듈 중심 — '채용 모듈', '시뮬레이션 모듈'처럼 기능별로 선을 그어 구현
  3. 필요할 때 분리 — 특정 기능의 서버만 터질 것 같을 때, 이미 나눠둔 그 '모듈'만 떼어내어 MSA로 독립

핵심: 모듈러 모놀리식은 "MSA를 포기하는 것"이 아니라 "MSA로 갈 준비를 해둔 채 시작하는 것" 입니다. 모듈 경계를 제대로 그어두면, 나중에 그 선을 따라 잘라내기만 하면 MSA가 됩니다.

6.4 MSA를 하네스 엔지니어링으로 확장할 때

MSA를 그냥 쪼개기만 하면 관리가 안 됩니다. 다섯 가지를 추가해야 합니다.

  1. 표준 보일러플레이트와 공통 모듈 분리
    • templates/microservice-base (표준 뼈대)
    • libs/common (인증·로깅·에러핸들링)
  2. API Contract를 엄격히 정의 — Swagger/OpenAPI 또는 gRPC(ProtoBuf)
  3. API Gateway 도입
  4. 분산 추적 + 중앙 로깅 — Jaeger/Zipkin, ELK
  5. 모노레포 + Docker 이미지화 — Turborepo/Nx

libs/common 을 분리하는 것이 곧 "하네스" 입니다. 규격화된 통로를 만들어두는 일입니다.

6.5 멀티레포에서 모노레포로 옮기기

git remote -v 로 시작합니다. -v(verbose)를 붙이면 현재 로컬 저장소에 연결된 원격 저장소의 별칭(alias)과 URL 이 보입니다.

  • fetch: 원격에서 최신 변경 사항을 가져올 때 쓰는 주소
  • push: 로컬 작업을 원격으로 업로드할 때 쓰는 주소

왜 먼저 확인하는가

  • 주소 확인 (이사 준비) — 여러 폴더(backend, frontend, docs)를 하나로 합치려면 각 폴더가 인터넷상 어느 주소와 연결돼 있는지 알아야 합니다. 엉뚱한 주소의 코드를 가져오는 실수를 막습니다.
  • 데이터 흐름 검증 — 보통 fetch와 push 주소는 같지만 설정에 따라 다를 수 있습니다.
  • 통합의 기초 — 각 서비스의 커밋 히스토리를 보존하며 합치는 것이 중요합니다.

전환 절차

# 1. 최초 깃 주소 확인
git remote -v

# 2. 기존 폴더 삭제
Remove-Item -Recurse -Force backend
Remove-Item -Recurse -Force frontend
Remove-Item -Recurse -Force docs

# 3. 루트에서 서브모듈 등록
# 4. 루트에서 브랜치·리모트 설정 후 푸시
# 5. 서브모듈이 붙은 상태의 깃허브 확인

비유하면: MSA(기존)는 각각 다른 건물에 있는 작은 상점들, 모듈러 모놀리식(변경 후)은 한 건물 안에 구역이 나뉜 백화점. 지금 하는 일은 백화점에 입점시키기 위해 각 상점의 '정확한 원래 주소' 를 확인하는 단계입니다.

6.6 Copy와 Clone은 다르다

같이 정리해 둡시다. 이것도 "이력이 따라오는가" 라는 하나의 축입니다.

CopyClone
무엇현재 파일 값만 복사프로젝트의 전체 역사(Commit History) 와 구조를 통째로 복제
결과과거 기록 상실독립적인 작업소가 구축됨
GitDownload ZIPgit clone
이후push 불가원격과 동기화·push 가능

7. 데이터베이스 고르기

7.1 상위 분류는 딱 둘

데이터베이스
├── 관계형 (RDBMS)  — 테이블(행·열) + SQL
└── 비관계형 (NoSQL)
    ├── Document    — MongoDB
    ├── Key-Value   — Redis, Memcached
    ├── Wide-Column — Cassandra, HBase
    └── Graph       — Neo4j

+ 특수 목적: 인메모리(Redis), 시계열(InfluxDB), 검색엔진(Elasticsearch)

7.2 RDBMS vs NoSQL

RDBMSNoSQL
구조테이블(행/열) + SQL종류마다 다름
강점일관성·정확성(ACID), 복잡한 조인 가능, 데이터 중복 최소화유연한 구조, Scale-out 쉬움
약점Scale-out이 어려움조인·일관성 보장이 약함
제품MySQL, PostgreSQL, Oracle, SQL Server아래 표 참조
언제결제·주문·회원 관리 등 무결성이 절대적인 서비스로그, 캐시, 콘텐츠, 관계망

NoSQL 4종

종류특징대표 제품용도
DocumentJSON 유사 문서 형태MongoDB콘텐츠 관리, 사용자 프로필
Key-Value키-값 쌍 (매우 빠름)Redis, Memcached캐싱, 세션, 실시간 순위
Wide-Column행마다 컬럼이 다를 수 있음Cassandra, HBase대규모 로그, IoT
Graph데이터 간 관계(연결) 를 저장Neo4j소셜 네트워크, 추천 엔진

7.3 폴리글랏 퍼시스턴스

정의: 하나의 시스템 안에서 서비스 특성에 따라 서로 다른 DB를 쓰는 전략. "다국어(polyglot)를 쓰는 영속성(persistence)"이라는 뜻입니다.

결제는 PostgreSQL, 세션은 Redis, 추천은 Neo4j — 이런 식으로 각 서비스에 맞는 DB를 씁니다. MSA에서 자연스럽게 나오는 전략입니다. 서비스가 이미 독립돼 있으니 DB도 따로 고를 수 있습니다.

7.4 선택 가이드

  • 비즈니스 복잡도가 높다면 → PostgreSQL (DDD와 잘 어울림)
  • 구조가 자주 바뀌고 확장이 중요하면 → MongoDB
  • 조회 성능이 극도로 중요하면 → Redis 를 캐시 어댑터로

PostgreSQL을 이 수업에서 쓰는 이유 (읽는 법: "피시퀄")

  • 확장 가능성 — 표준 관계형 DB의 안정성과 비정형/벡터 데이터 처리 능력을 동시에 보유. AI 시스템의 유연한 확장을 지원
  • 표준 준수 — 높은 SQL 표준 준수율을 바탕으로 DDD의 풍부한 도메인 모델을 영속성 계층에 손실 없이 반영
  • 엔터프라이즈 신뢰성 — RedHat(RHEL) 환경과의 긴밀한 통합으로 B2B 서비스가 요구하는 고가용성·무결성 보장

7.5 엔터티(Entity) — DB 설계의 단위

엔터티는 업무에 필요하고 유용한 정보를 저장·관리하기 위한 '어떤 것(Thing)' 입니다. 데이터베이스의 테이블(Table) 과 유사한 개념입니다.

  • 인스턴스(Instance): 엔터티 내의 개별 데이터 행(Row)
  • 속성(Attribute): 엔터티의 세부 정보 항목(Column)

적절한 엔터티인지 확인하는 6가지 기준

  1. 업무 연관성 — 시스템 구축 목적에 부합하고 업무에 반드시 필요한 정보인가
  2. 유일한 식별자 — 각 인스턴스를 유일하게 구분할 주식별자(PK)가 있는가
  3. 다수의 인스턴스 — 최소 2개 이상의 데이터 집합인가 (하나뿐이면 상수지 엔터티가 아님)
  4. 프로세스 이용 — 업무 로직 내에서 실제로 쓰이는가 (고립된 엔터티는 부적절)
  5. 속성 포함 — 주식별자 외에 그 객체를 설명하는 일반 속성이 하나 이상 있는가
  6. 관계 존재 — 다른 엔터티와 최소 1개 이상의 유기적 관계를 맺고 있는가

유무형에 따른 분류

종류설명예
유형 엔터티물리적 형태가 있고 지속적으로 사용됨고객, 사원, 강사
개념 엔터티물리적 형태 없이 개념적으로 존재상품, 종목, 보험
사건 엔터티비즈니스 프로세스 실행 시 생성됨주문, 체결, 취소

발생 시점에 따른 분류

종류설명예
기본 엔터티독립적으로 생성되며 다른 엔터티의 부모 역할 (키 엔터티)고객, 상품, 부서
중심 엔터티기본 엔터티에서 파생되어 업무의 중심이 됨계좌, 주문
행위 엔터티2개 이상의 엔터티 상호작용으로 발생하며 이력이 남음주문 이력, 체결 이력

7.6 SQL과 CRUD

CRUD 는 데이터를 다루는 네 가지 기본 동작입니다. 각 동작이 SQL과 HTTP에서 어떻게 불리는지 짝지어 외우세요.

동작뜻SQLHTTP
Create생성INSERTPOST
Read조회SELECTGET
Update수정UPDATEPUT, PATCH
Delete삭제DELETEDELETE

7.7 검색은 어떻게 빠른가

검색엔진이 데이터를 찾는 방법은 크게 둘입니다.

  • 글자로 찾기 — 해시, 딕셔너리 방식
  • 숫자로 찾기 — 인덱스 방식

딕셔너리(Dictionary) 방식은 수많은 문서에서 추출된 단어(Term)를 체계적으로 목록화하는 기법입니다. 역색인(Inverted Index) 구조에서 "어떤 단어가 어디에 있는지"를 빠르게 찾는 이정표 역할을 합니다.

  • 주요 알고리즘: 해시 테이블(Hash Table), B-Tree, Trie, FST(Finite State Transducer)
  • 목표: 검색 속도 최적화, 용어 정규화, 메모리 효율 극대화

파이썬의 딕셔너리도 같은 원리입니다. 문자열 키를 해시 함수로 고유한 숫자로 변환해 저장하기 때문에 초고속 검색이 가능합니다.

📚 더 읽을 것: 『비전공자를 위한 데이터베이스 입문』 p.61 / 『점프 투 파이썬』 p.93(딕셔너리)


8. 데이터가 흘러가는 전체 길

여기까지의 조각을 하나로 이으면 이런 그림이 됩니다. 이 장의 종합입니다.

[브라우저 / 화면]        함수 (React 컴포넌트)          ← 속성 없음, 기능만
      │
      │  Axios(기관차)가 JSON(화물)을 API(선로)로 실어나름
      │  REST(교통법규)가 그 방식을 규정
      ▼
[FastAPI 라우터]        함수 (Control)                 ← 교통 정리원
      │
      │  Schema 로 입력 검증
      ▼
[Use Case / Service]    객체 (Model)                   ← 속성 + 기능
      │
      │  DTO 로 순수 데이터만 뽑아 전달
      ▼
[Repository (Port)]     인터페이스 — 추상               ← "저장해줘"라고만 말함
      │
      │  실제 구현체(Adapter)가 주입됨
      ▼
[PG Repository]         구상 — SQLAlchemy 사용
      │
      │  ORM 이 객체 ↔ 테이블 행을 변환
      ▼
[PostgreSQL / Neon]     개체 (Entity)                  ← 속성만, 기능 없음

8.1 화살표마다 형태가 바뀐다

이게 이 구조의 핵심입니다. 각 경계를 넘을 때 데이터의 모양이 달라집니다.

구간데이터의 형태왜 바꾸나
브라우저 → 라우터JSON 텍스트언어가 달라도 읽을 수 있어야 하므로
라우터 → 유스케이스Schema 객체형식이 맞는지 검증하고 들여보내려고
유스케이스 → 리포지토리DTO비즈니스 로직이 DB 구조를 모르게 하려고
리포지토리 → DBORM Entity테이블 구조에 맞춰야 저장되므로

8.2 통신 계층을 물류로 보기

프론트엔드와 백엔드 사이는 하나의 물류 시스템입니다.

요소물류 비유기술적 설명
객체 (Object)화물 (Cargo)전달할 실제 데이터. JSON {키: 값} 형태로 포장되어 이동
API선로 (Track)데이터가 이동할 전용 통로. 특정 주소(URL)와 규칙을 가짐
Axios기관차 (Engine)화물을 싣고 선로 위를 실제로 움직이게 하는 동력(라이브러리)
REST교통 법규 (Rule)선로를 어디에 깔고 어떤 화물을 어떻게 보낼지 정한 표준 설계 원칙

요청(Request): 프론트엔드 → 백엔드

  • Method: 어떤 행위를 할 것인가? (GET, POST, PUT, DELETE)
  • URL: 어느 정거장(API 엔드포인트)으로 갈 것인가?
  • Payload: 어떤 화물(객체)을 보낼 것인가?

응답(Response): 백엔드 → 프론트엔드

  • Status Code: 처리 결과 상태

    코드물류 비유의미
    🟢 200 (OK)배송 성공화물 도착
    🟡 404 (Not Found)선로 없음API 주소 오류
    🔴 500 (Error)기지 사고서버 오류
  • Data: 백엔드가 보내준 실제 결과물(객체)

결론: API(선로)가 길을 열고, REST(법규)가 질서를 잡으며, Axios(기동 수단)가 객체(화물)를 실어나름으로써 비로소 웹 서비스의 데이터 통신이 완성됩니다.

8.3 이 그림에 아직 이름이 없다

지금 그린 이 구조가 헥사고날 아키텍처입니다. 이름만 아직 안 붙었을 뿐입니다. 6주차에 adapter/ app/ports/ domain/ 이라는 폴더 이름으로 다시 만나게 됩니다.