"코드 정리해달라고 했더니 AI가 물어봐요. '어떻게 정리할까요?' 저도 모르겠어서 '알아서 해줘'라고 했더니 매번 다른 방식으로 짜요. 나중에 보면 스타일이 제각각이라 뭐가 뭔지..."

맞아요. AI한테 "정리해줘"만 하면 그때그때 다르게 만들어요. 어떤 건 파일 하나에 다 넣고, 어떤 건 파일 10개로 쪼개고... 일관성이 없으니까 나중에 코드 보면 헷갈리는 거예요.

왜 이런 일이 생길까요?

"어떻게 정리할지" 기준을 안 줘서 그래요. 같은 문제인데도 AI가 매번 다른 방식으로 해결하면, 코드가 통일성 없이 뒤죽박죽 돼요.

근데 이게 비단 여러분만의 문제는 아니에요.

2024년부터 AI가 프로젝트 전체를 만들 수 있게 됐어요. 처음엔 신기했죠. "와, 정말 뭔가 나오네?"

근데 여기서 멈추는 사람이 대부분이에요.

처음엔 뭔가 나와요. 근데 기능 추가하려니까 꼬여요. 매번 다르게 짜니까, 나중에 수정하려면 어디를 고쳐야 할지 모르겠는 거죠.

차이를 만드는 건 AI가 아니라 "어떻게 시키느냐"예요.

이걸 해결하는 게 **디자인 패턴(Design Pattern)**이에요. "이런 상황에선 이렇게 짜라"는 검증된 해결책이죠.

디자인 패턴을 알면 AI한테 **"이 컴포넌트는 Container-Presenter 패턴으로 분리해줘"**라고 정확히 말할 수 있어요. 그러면 AI가 일관된 방식으로 코드를 짜줘요.

중요한 건, AI가 만들어주면 끝이 아니에요.

기능 단위로 직접 확인해야 해요. 버튼 만들었으면 눌러보고, 저장 기능 만들었으면 저장해보고. 이 "확인 → 피드백" 과정이 없으면 나중에 다 꼬여요.


이 글을 읽고 나면

  • 디자인 패턴이 뭔지, 왜 필요한지 알 수 있어요
  • 자주 쓰는 디자인 패턴 5가지를 구분할 수 있어요
  • 상황에 맞는 패턴을 선택할 수 있어요
  • AI한테 "이 패턴으로 해줘"라고 말할 수 있어요

디자인 패턴이 뭔가요?

디자인 패턴반복되는 문제를 해결하는 검증된 방법이에요.


PART 4 복습: 아키텍처에서 디자인 패턴으로

17편에서 코드를 어떻게 구조화할지를 배웠죠?

오늘 배울 것은: 그 안에서 코드를 어떻게 짤지

  • 17편: 전체 구조를 어떻게? → 레이어드 / MVC / 클린
  • 18편(오늘): 세부 코드를 어떻게? → 싱글톤 / 팩토리 / 옵저버

비유하면:

  • 아키텍처 = 집 설계도 (방을 어떻게 배치할까?)
  • 디자인 패턴 = 가구 배치법 (침대는 어떻게 놓을까?)

왜 디자인 패턴이 필요한가요?

패턴 없이 코드를 짜면 이런 일이 생겨요.


아키텍처 vs 디자인 패턴

헷갈릴 수 있으니 정리해볼게요.


바이브 코더가 알아야 할 디자인 패턴 5가지

실무에서 자주 쓰이는 패턴만 알면 돼요. 너무 많이 알 필요 없어요.

디자인 패턴 3대장


1. 싱글톤: 하나만 만들기

싱글톤 패턴객체를 딱 하나만 만드는 패턴이에요.

싱글톤 패턴 예시: 로그인 상태


2. 팩토리: 찍어내기

팩토리 패턴비슷한 객체를 찍어내는 패턴이에요.

팩토리 패턴 예시: 버튼 컴포넌트


3. 옵저버: 구독하기

옵저버 패턴상태 변화를 여러 곳에 알리는 패턴이에요.

옵저버 패턴 예시: 로그인 상태


4. 전략: 방법 바꾸기

전략 패턴상황에 따라 다른 방법을 쓰는 패턴이에요.

전략 패턴 예시: 결제


5. Container-Presenter: 역할 나누기

Container-Presenter 패턴로직과 화면을 분리하는 패턴이에요.

Container-Presenter 예시: 상품 목록


패턴 조합하기: 실전 예시

실제로는 여러 패턴을 조합해서 써요.


AI한테 이렇게 요청하세요

패턴을 알면 AI한테 어떻게 짤지 정확히 말할 수 있어요.

상황 1: 장바구니 상태 관리

나쁜 예 (패턴 언급 없음)

나: "장바구니 기능 만들어줘"

→ AI가 알아서 만드는데, 페이지마다 상태가 따로 생겨서 동기화 안 될 수 있어요.

좋은 예 (싱글톤 + 옵저버)

나: "Next.js 앱에서 장바구니 상태 관리할 건데,
    싱글톤 패턴으로 앱 전체에서 하나만 만들어줘.

    그리고 옵저버 패턴으로 장바구니 변경되면
    헤더의 장바구니 아이콘, 장바구니 페이지, 결제 페이지가
    자동으로 업데이트되게 해줘.

    React Context나 zustand 같은 걸로 구현해줘."

→ AI가 싱글톤으로 상태 하나 만들고, 옵저버로 자동 업데이트 구현해요.


상황 2: 상품 카드 컴포넌트

나쁜 예

나: "상품 카드 만들어줘"

좋은 예 (팩토리 + Container-Presenter)

나: "상품 카드 컴포넌트 만들 건데, 두 가지 패턴 써줘.

    1. 팩토리 패턴으로 카드 타입별 생성
       - 일반 상품 카드
       - 할인 상품 카드
       - 품절 상품 카드

    2. Container-Presenter로 분리
       - ProductCardContainer: API에서 상품 데이터 가져오기
       - ProductCardPresenter: 받은 데이터로 화면만 그리기

    나중에 카드 디자인 바꿀 때 Presenter만 수정하면 되게."

상황 3: 결제 기능

나쁜 예

na: "결제 기능 만들어줘"

좋은 예 (전략 패턴)

나: "결제 기능 만들 건데, 전략 패턴으로 해줘.

    결제 수단:
    - 카드 결제 (Bootpay)
    - 계좌이체 (Bootpay)
    - 간편결제 (카카오페이)

    나중에 네이버페이 추가할 수도 있으니까
    새 전략만 추가하면 되게 구조 잡아줘.

    PaymentStrategy 인터페이스 만들고,
    각 결제 수단별로 구현체 만들어줘."

실제 대화 예시

AI랑 패턴 정하면서 대화할 때 이렇게 해요.

┌───────────────────────────────────────────────────────────────────────┐ │ 1단계: 기술 스택과 패턴 결정 │ ├───────────────────────────────────────────────────────────────────────┤ │ │ │ 나: "할 일 관리 앱 만들 건데, Next.js + Supabase 쓸 거야." │ │ │ │ AI: "할 일 목록 컴포넌트 어떻게 만들까요?" │ │ │ │ 나: "Container-Presenter 패턴으로 분리해줘. │ │ │ │ TodoListContainer: │ │ - Supabase에서 할 일 목록 가져오기 │ │ - 추가/삭제/완료 처리 │ │ - 로딩/에러 상태 관리 │ │ │ │ TodoListPresenter: │ │ - 받은 데이터로 리스트 렌더링만 │ │ - 버튼 클릭하면 Container 함수 호출 │ │ │ │ 나중에 UI만 바꿀 수 있게." │ │ │ └───────────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────────┐ │ 2단계: 세부 구조 협의 │ ├───────────────────────────────────────────────────────────────────────┤ │ │ │ AI: "알겠어요. 그럼 할 일 추가 버튼은 여러 개 만들 건가요? │ │ 메인 화면, 상세 화면, 퀵 추가 버튼..." │ │ │ │ 나: "맞아. 팩토리 패턴으로 버튼 타입별로 만들어줘. │ │ createButton(type)으로 주요/보조/작은 버튼 찍어내게." │ │ │ │ AI: "네, 그럼 구조 제안합니다: │ │ │ │ components/ │ │ - TodoListContainer.tsx (데이터 + 로직) │ │ - TodoListPresenter.tsx (UI만) │ │ - buttonFactory.ts (버튼 생성 로직) │ │ │ │ hooks/ │ │ - useTodos.ts (할 일 상태 관리) │ │ │ │ useTodos는 싱글톤처럼 앱 전체에서 하나만 쓰고, │ │ 옵저버 패턴으로 할 일 바뀌면 자동 업데이트할게요." │ │ │ │ 나: "좋아. 그렇게 만들어줘." │ │ │ └───────────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────────┐ │ 3단계: 구현 및 기능 단위 확인 │ ├───────────────────────────────────────────────────────────────────────┤ │ │ │ AI: "기본 구조 만들었어요. 확인해보세요." │ │ │ │ [기능 단위로 직접 확인] │ │ 1. 할 일 추가 버튼 클릭 │ │ → 입력 폼 잘 뜸 ✅ │ │ │ │ 2. 할 일 입력 후 저장 │ │ → 리스트에 바로 추가됨 ✅ │ │ │ │ 3. 새로고침 │ │ → DB에서 다시 가져옴 ✅ │ │ │ │ 4. 완료 체크박스 클릭 │ │ → 어? 체크는 되는데 리스트 갱신이 안 되네? │ │ │ │ 나: "완료 처리하면 리스트가 자동으로 갱신되게 해줘." │ │ │ │ AI: "useTodos에 옵저버 패턴 추가할게요. │ │ 완료 상태 바뀌면 구독 중인 컴포넌트들이 자동 업데이트돼요." │ │ │ │ [다시 확인] │ │ - 완료 체크 → 리스트 자동 업데이트 ✅ │ │ - 버튼 3종류 스타일 일관성 ✅ │ │ - 새로고침해도 데이터 유지 ✅ │ │ │ │ 💡 여기서 뭐가 중요했나요? │ │ - 패턴 이름을 정확히 말함 (Container-Presenter, 팩토리) │ │ - 왜 그 패턴을 쓰는지 이유 제시 ("나중에 UI만 바꿀 수 있게") │ │ - AI가 제안하면 확인 후 진행 │ │ - 기능 단위로 직접 확인하고 피드백 (가장 중요!) │ │ │ └───────────────────────────────────────────────────────────────────────┘


패턴 선택 가이드

어떤 상황에 어떤 패턴을 쓸까요?


코드 문법 몰라도 돼요

💡 잠깐, 저는 코드를 못 짜는데요?

괜찮아요. 패턴 개념만 알면 돼요.

여러분이 알아야 할 것:
✅ 싱글톤 = 하나만 만들기 (로그인 상태)
✅ 팩토리 = 찍어내기 (버튼 여러 개)
✅ 옵저버 = 구독하기 (상태 변화 알림)
✅ 전략 = 방법 바꾸기 (결제 수단)
✅ Container-Presenter = 로직/UI 분리

여러분이 몰라도 되는 것:
❌ 패턴을 코드로 어떻게 구현하는지
❌ 클래스, 인터페이스 문법
❌ GoF 디자인 패턴 23개

→ AI한테 "싱글톤으로 해줘"라고 말만 하면 돼요.
→ AI가 패턴대로 코드 짜줘요.

주의사항: 패턴이 정답은 아니에요

⚠️ 모든 걸 패턴으로 짤 필요는 없어요

근데 이것만은 지키세요:

  • 프론트엔드는 Container-Presenter로 시작 (로직/UI 분리)
  • 앱 전역 상태는 싱글톤으로 (로그인, 설정 등)
  • 비슷한 컴포넌트 3개 이상이면 팩토리 고려
  • 여러 곳 업데이트 필요하면 옵저버 고려

다음 단계: 상태 관리

패턴을 알았으면 이제 상태를 어떻게 관리할지 정하는게 중요해요.

오늘 배운 것: 코드를 어떻게 짤지
              → 싱글톤, 팩토리, 옵저버, 전략, Container-Presenter

다음 편: 데이터(상태)를 어디에 둘지
         → 전역 상태 vs 로컬 상태
         → "로그인 상태는 전역, 폼 데이터는 로컬"

오늘의 핵심 정리


셀프체크

이 글을 이해했다면 아래 질문에 답할 수 있어요:

  • 로그인 상태를 관리할 때 어떤 패턴을 쓰면 좋을까요? (하나만 있어야 함)
  • 주요/보조/위험 버튼 3종류를 만들 때 어떤 패턴이 좋을까요?
  • 할 일 목록 컴포넌트를 로직과 UI로 분리하려면 어떤 패턴을 쓰면 되나요?
  • 싱글톤 패턴 (앱 전체에서 하나의 로그인 상태만 유지)
  • 팩토리 패턴 (createButton(type)으로 타입별 버튼 찍어내기)
  • Container-Presenter 패턴 (Container는 데이터, Presenter는 UI)

다음 글 예고

오늘은 디자인 패턴을 배웠어요. 싱글톤, 팩토리, 옵저버 같은 코드 작성 패턴이요.

근데 패턴만 알면 부족해요. "데이터(상태)를 어디에 둘지"도 중요해요.

다음 글에서는 상태 관리 개념을 알아볼게요.

19편: 상태 관리 개념

  • "로그인 상태는 어디에? 폼 데이터는 어디에?"
  • 전역 상태 vs 로컬 상태
  • "로그인 상태는 전역으로, 폼 데이터는 로컬로 관리해줘"

패턴으로 코드 짜는 법을 배웠으면, 이제 상태를 어떻게 관리할지 배워요.


이 시리즈 로드맵

PART 4: 기술 개념 - 설계
[ 16편 ] 자료구조 개념 ✅
   ↓
[ 17편 ] 아키텍처 개념 ✅
   ↓
[ 18편 ] 디자인 패턴 개념 (지금 여기!)
   ↓
[ 19편 ] 상태 관리 개념
   ↓
[ 20편 ] AI한테 설계 지시하는 법
   ↓
  ...

궁금한 점이나 다뤘으면 하는 주제가 있으면 댓글로 남겨주세요!