포스트

TIL 2026-03-18

TIL 2026-03-18

3/18 | 4번 과제 — 연금술 공방 관리 시스템

생성일: 2026년 3월 13일 오후 5:29

📗 4번 과제 — 연금술 공방 관리 시스템

학습 목표

  • 프로그래밍 기본기 : 변수, 함수, 조건문, 반복문 적재적소 활용
  • 객체지향 설계 (상속/다형성) : 아이템과 제작법을 체계적으로 설계
  • 데이터 관리 (STL) : vector, map 컨테이너로 창고·레시피 관리
  • 클린 코드 (SOLID) : 수정이 쉬운 구조 설계

구현 기능 정리

✅ 필수 기능

기능설명
레시피 추가물약 이름 + 재료 목록(여러 개)을 입력받아 등록
전체 레시피 출력등록된 모든 레시피와 재고 출력
이름으로 검색물약 이름으로 정확히 1개 검색
재료로 검색특정 재료가 포함된 모든 레시피 검색

⭐ 도전 기능

기능설명
자동 초기 재고레시피 추가 시 재고 자동 3개 세팅
물약 지급 (이름)재고 1개 이상일 때만 지급, 재고 -1
물약 지급 (재료)해당 재료 포함 물약 중 재고 있는 것 모두 지급
공병 반환재고 +1, 최대 3개 초과 불가

클래스 설계 (책임 분리 — SRP)

1
2
3
4
PotionRecipe     → 데이터만 보관 (이름, 재료 목록)
RecipeManager    → 레시피 추가 / 이름 검색 / 재료 검색
StockManager     → 재고 초기화 / 지급 / 반환 / 조회
AlchemyWorkshop  → 위 세 클래스를 조합해 공방 기능 제공 (Facade)

코드 작성 과정

  1. 기존 제공 코드 분석
    • PotionRecipe : 이름 + 단일 재료 → 다중 재료(vector<string>)로 변경 필요
    • AlchemyWorkshop : 레시피 관리 + 출력 + 향후 재고까지 혼재 → SRP 위반
    • 기존 코드 수정 최소화를 위해 새 클래스(RecipeManager, StockManager)를 추가하는 방향 선택
  2. 필수 기능 구현
    • RecipeManager::FindRecipeByName() → 이름 일치(==) 비교, 없으면 nullptr
    • RecipeManager::FindRecipesByIngredient() → 재료 목록 순회, 결과 vector 반환
  3. 도전 기능 구현
    • StockManager : map<string, int>로 물약별 재고 관리
    • MAX_STOCK = 3 : static constexpr로 선언 → 정책 변경 시 한 곳만 수정 (OCP)
    • DispensePotion() : 재고 > 0 이면 감소 후 true, 아니면 false
    • ReturnPotion() : 재고 < MAX_STOCK 이면 증가, 아니면 안내 메시지
  4. 개선 적용
    • ReadLine() 헬퍼 함수 추가 : cin.ignore + getline 패턴 중복 6곳 → 1곳으로 통일
    • 빈 문자열 입력 방어 : 검색/지급/반환 모든 진입점에 empty() 체크 추가
    • PrintIngredients() 헬퍼 : 재료 목록 출력 중복 코드 3곳 → 1곳으로 통일

코드 유의점

설계 원칙

  • SRP : 각 클래스가 바뀌어야 할 이유가 하나인가?
    • RecipeManager는 레시피 변경 시에만, StockManager는 재고 정책 변경 시에만 수정
  • OCP : 새 기능 추가 시 기존 코드를 건드리지 않는가?
    • MAX_STOCK 상수 분리로 재고 정책 변경에 기존 로직 수정 불필요
    • 향후 재고 정책 다양화 시 IStockPolicy 인터페이스로 확장 가능

입력 검증

  • 숫자가 아닌 메뉴 입력 → cin.fail() 감지 후 복구
  • 빈 물약 이름 / 빈 재료 이름 → empty() 체크 후 안내 메시지
  • 재료 0개로 레시피 추가 시도 → 취소 메시지 출력

에러 처리 메시지 목록

상황출력 메시지
중복 레시피 추가이미 존재하는 레시피입니다
이름 검색 결과 없음이름의 레시피를 찾을 수 없습니다
재료 검색 결과 없음재료를 사용하는 레시피가 없습니다
재고 부족 지급재고가 부족합니다
MAX 초과 반환창고가 가득 찼습니다
없는 레시피 지급/반환레시피가 존재하지 않습니다
빈 입력이름을 입력해주세요

최종 코드

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.