TIL_030: 객체지향적 설계

김펭귄·2025년 9월 8일

Today What I Learned (TIL)

목록 보기
30/139

오늘 학습 키워드

  • 객체지향적 설계

1. 객체지향적 설계

부모, 자식 클래스 간 헤더

  • 자식 클래스 헤더가 부모 클래스 헤더를 포함

  • main에서는 필요한 구체 클래스 헤더(자식 클래스)만 포함

  • 부모 클래스에서 자식 클래스 헤더를 포함하는 것은 지양 (순환 참조, 결합도 증가)

권장 패턴

// Monster.h (부모)
class Monster { ... };

// Slime.h (자식)
#include "Monster.h"
class Slime : public Monster { ... };

// main.cpp
#include "Slime.h"  // Monster.h는 자동 포함됨

로그 시스템 설계 패턴

문제 상황

  • 여러 클래스(Store, Battle 등)의 활동을 LogManager가 관찰하고 기록

  • 각 클래스마다 public static 변수를 가지고, 이를 LogManager가 관찰하고 기록하려 하였음

  • 한계: 캡슐화 위반, 의도치 않은 수정 가능

해결 방안들

  1. Observer 패턴 (의존성 주입 DI)
class ILogObserver {	// 추상화된 인터페이스로
public:
    virtual void onEvent(const std::string& event, int value) = 0;
};

class LogManager : public ILogObserver { ... };	// 구체 클래스

class Store {
    ILogObserver* logger;	// 인터페이스에 의존
public:
    Store(ILogObserver* logger) : logger(logger) {}
};
  1. 싱글톤 패턴 (글로벌 접근)
class LogManager {
public:
    static LogManager* getInstance() {
    	if (instance == nullptr)
        	instance = new LoaManager();
        return instance;
    }
};
  1. 이벤트 버스 패턴
  • 이벤트를 시스템 전체에 발송하고 LogManager가 구독하여 처리

  • 느슨한 결합으로 확장성과 유연성 확보

설계 방식 선택 기준

  • 의존성 주입(DI)을 선택하는 경우

    1. 테스트, 확장성, 유지보수성이 중요할 때
    2. 여러 구현체 교체 가능성
    3. 클래스 간 의존관계를 명확히 알림
    4. 대규모/장기 프로젝트
  • 글로벌 접근(싱글톤)을 선택하는 경우

    1. 간단하고 빠른 개발이 필요할 때
    2. 변경 가능성이 낮을 때
    3. 작은 프로젝트나 프로토타입
    4. 전역적으로 단일 인스턴스만 필요할 때
  • 추상화(인터페이스) 사용 기준

    1. 여러 구현체가 예상될 때 (FileLogger, NetworkLogger 등)
    2. 테스트 시 Mock 객체 필요할 때 (빠른 테스트 가능)
    3. 의존성 분리로 결합도 감소 필요할 때
    4. 복잡한 시스템에서 확장성 확보
  • 구체 클래스만 사용하는 경우

    1. 단순하고 변경 가능성 낮음
    2. 단일 구현체만 존재
    3. 작고 빠른 개발이 우선
    4. 테스트나 확장성이 상대적으로 덜 중요

다음 학습

profile
반갑습니다

0개의 댓글