learn

프로그램을 처음부터 설계하는 과정

프로그램을 처음부터 설계하는 과정

"시간표 관리 프로그램을 만들어 줘"라는 한 줄의 요청을 받았을 때, 코드를 쓰기 전에 머릿속에서 일어나는 전체 과정을 정리한다.

설계의 본질: 결정을 점진적으로 좁혀가기

좋은 설계의 핵심은 추상에서 구체로 내려가는 것이다. 처음부터 코드를 짜는 게 아니라, "무엇을 → 어떤 개념으로 → 어떤 구조로"를 단계적으로 결정한다. 상위 결정(아키텍처)이 하위 구현의 선택지를 결정하기 때문에, 순서가 중요하다.

피드백 루프가 있는 이유: 구현 중 빠진 요구사항이나 아키텍처의 한계를 발견하게 된다. 설계는 일회성이 아니라 반복적 정제 과정이다.


1. 요구사항 분석 — 암묵적 가정을 명시적으로

"시간표 관리 프로그램"이라는 한 줄에는 놀라울 정도로 많은 가정이 숨어있다. 이걸 구체적 질문으로 분해하는 것이 첫 단계다:

  • 누가 쓰나? → 대학생 1명 (개인용)
  • 핵심 기능은? → 수업 추가/삭제, 시간 충돌 검사, 주간 뷰
  • 플랫폼은? → 데스크톱 앱
  • 데이터 영속성? → 앱을 꺼도 데이터 유지
  • 확장 가능성? → 알림, 과제 관리, 학점 계산이 붙을 수 있음

이 단계의 목표는 모호함을 제거하는 것이다. 답을 모를 때는 가정을 명시하고 진행한다.


2. 도메인 모델링 — 현실 세계의 개념 추출

코드가 아니라 현실의 개념 관계를 먼저 그린다:

여기서 핵심 설계 판단: Course와 Lecture를 분리한다. "알고리즘" 수업 하나가 "월 10시 / 수 10시" 같이 여러 시간대를 가질 수 있다. Course는 논리적 단위, Lecture는 물리적 시간 단위다. 이 분리가 나중에 충돌 검사 로직을 단순하게 만든다.


3. 아키텍처 선택 — 규모와 성격에 맞는 구조

같은 프로그램이라도 아키텍처에 따라 코드 구조가 완전히 달라진다. 대표적인 세 가지를 비교한다.

Layered Architecture (계층형)

가장 고전적이고 직관적인 구조. 각 층은 바로 아래 층만 호출할 수 있다:

"수업 추가" 요청이 처리되는 흐름:

MVC (Model-View-Controller)

Layered와 비슷하지만 Controller가 중재자 역할을 명시적으로 한다:

핵심적 차이: MVC에서는 Model이 View에 직접 알림을 보낼 수 있다 (observer-pattern|Observer 패턴). Layered에서는 항상 위에서 아래로만 흐른다.

Event-Driven Architecture

모듈 간 결합을 최소화하고 싶을 때:

각 컴포넌트가 서로를 직접 모르고, 이벤트만 주고받는다. "수업이 추가됐다"는 이벤트 하나에 저장소, 알림, UI가 각각 독립적으로 반응한다. 새 기능을 추가할 때 기존 코드를 건드리지 않아도 된다.

비교

| | Layered | MVC | Event-Driven | |---|---|---|---| | 복잡도 | 낮음 | 중간 | 높음 | | 결합도 | 층 간 의존 | Controller 중심 | 거의 없음 | | 확장성 | 보통 | 보통 | 높음 | | 적합한 규모 | 소~중 | 중 | 중~대 | | 시간표 앱에? | ✅ 적합 | ✅ 적합 | ⚠️ 과할 수 있음 |


4. 컴포넌트 분해 — Single Responsibility

Layered를 선택했다면, 각 모듈이 하나의 책임만 갖도록 나눈다:

conflict_checker는 충돌 검사만, file_persistence는 파일 I/O만. 이것이 single-responsibility-principle|Single Responsibility Principle이다.


5. 데이터 설계

로컬 JSON 파일로 저장하는 경우:

{
  "semester": {
    "name": "2026-1학기",
    "start": "2026-03-02",
    "end": "2026-06-19"
  },
  "courses": [
    {
      "id": "algo-01",
      "name": "알고리즘",
      "professor": "김교수",
      "credits": 3,
      "color": "#4a9eff",
      "lectures": [
        { "day": "mon", "start": "10:00", "end": "11:30", "room": "공7-301" },
        { "day": "wed", "start": "10:00", "end": "11:30", "room": "공7-301" }
      ]
    }
  ]
}

6. 핵심 알고리즘 — 시간 충돌 검사

시간표 앱의 핵심 로직. 두 Lecture가 겹치는 조건:

두 구간 [s1, e1)[s2, e2)의 겹침 조건: s1 < e2 AND s2 < e1. 이것은 interval-overlap|구간 겹침의 일반 공식으로, 시간표뿐 아니라 스케줄링 문제 전반에서 사용된다.