ice rabbit programming

[C++] GoF 패턴 간단 정리(3) - 생성 및 컬렉션 패턴 본문

Development/C++

[C++] GoF 패턴 간단 정리(3) - 생성 및 컬렉션 패턴

판교토끼 2026. 7. 17. 15:32
728x90

생성 및 컬렉션 패턴

Container & Iterator (반복자)

  • Thin Template Container: void* 기반의 컨테이너를 상속받는 얇은 템플릿(Thin Template) 기법을 사용하면, 강력한 타입 안정성을 챙기면서도 과도한 템플릿 인스턴스화에 따른 코드 폭발(Code Bloat)을 차단할 수 있어 하드웨어 제약이 큰 모바일이나 임베디드 라이브러리에서 매우 유용하다.
  • Iterator 패턴: 컨테이너 내부 구현(배열, 연결 리스트 등)을 노출하지 않고 요소에 순차적으로 접근할 수 있도록 돕는다. Java/C#의 인터페이스 기반 다형성 처리와 달리, C++의 STL 반복자는 런타임 가상 함수 호출 성능 저하를 방지하기 위해 연산자 오버로딩(++, *)과 컴파일 타임 템플릿 매칭 기법을 사용하며, 모든 관련 동작은 고성능 인라인 함수로 처리된다.

객체 생성의 추상화 패턴

  • Factory Method 패턴: 객체 생성을 위한 추상 인터페이스는 부모 클래스에 정의하되, 실제 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 파생 클래스에 위임한다.
  • Abstract Factory 패턴: 구체적인 클래스를 명시하지 않고, 서로 관련이 있거나 의존적인 객체들의 군(Family)을 생성하기 위한 인터페이스를 제공한다.
C++
 
// Abstract Factory 설계 구현 예시
struct IButton {
  virtual ~IButton() = default;
};

struct IFactory {
  virtual ~IFactory() = default;
  virtual IButton* CreateButton() = 0;
};

struct WinFactory : public IFactory {
  IButton* CreateButton() override {
    // 내부적으로 WinButton 인스턴스 반환
    return nullptr; 
  }
};

int main() {
  IFactory *pFactory = nullptr;
  
  if (/* 런타임 조건 분기 */ true) {
    pFactory = new WinFactory();
  }
  
  IButton *pBtn = pFactory->CreateButton();
  
  delete pBtn;
  delete pFactory;
  return 0;
}
  • Builder 패턴: 동일한 생성 절차(Director)를 따르되, 생성 각 단계의 세부 표현(Builder 인터페이스 구현체)을 분리하여 생성 결과가 각기 달라질 수 있도록 제어한다.
  • Prototype 패턴: 구체적인 클래스를 상속하여 생성하지 않고, 미리 등록되어 있는 견본 객체의 복사본을 만드는 Clone() 가상 함수를 호출하여 새로운 인스턴스를 생성한다.
  • Singleton 패턴: 애플리케이션 내에 오직 하나의 인스턴스만 보장되도록 제어한다. 생성자를 private화하고 복사 생성 및 대입을 금지(= delete) 처리한다.
    • DCLP (Double-Checked Locking Pattern): 과거 락 최소화를 위해 쓰였으나 컴파일러 재정렬(Reordering) 버그 위험이 있었다. C++11 이후부터는 std::atomic 메모리 모델을 적용하여 안전하게 구현할 수 있다.
    • Meyers' Singleton: static 지역 변수를 선언하여 객체를 반환하는 방식이다. C++11 규격에 의해 최초 접근 시 스레드 세이프(Thread-safe)한 지연 초기화(Lazy Initialization)가 보장되므로, 현재 C++ 환경에서 가장 안전하고 선호되는 형태다.
    • CRTP (Curiously Recurring Template Pattern): 싱글톤 로직을 재사용하기 위해 자식 클래스 타입을 템플릿 인자로 넘겨 상속받는 형태(class MyClass : public Singleton<MyClass>)를 말한다.

마치며

첫 글을 쓴지도 1년 반이라는 시간이 흘렀다.(아무래도 의도한 바는 아니지만...)

당시에도 copilot, chatgpt 등 AI를 이용한 개발이 막 태동하던 시기였지만 업무에 사용할 정도는 아니었는데, 그 사이에 이제는 AI agent 없이는 개발에 차질이 생길 정도로 많은 부분을 차지하게 되었다.

여러 날 사용해보고 고민도 해보면서 얻은 결론은, 코드를 읽고 이해하고 검증하는 능력이 더욱 중요해졌다는 것이다. 그리고 코드를 잘 읽기 위해서는 많이 써봐야 읽고 이해하는 능력이 길러진다고 생각한다. 또한 그러기 위해서는 설계나, 이번 포스팅에서 다룬 데이터를 논리적으로 처리하기 위한 구조(패턴)에 익숙할수록 더 빠르게 읽고 생산성을 높일 수 있다고 생각한다.

또 한 가지는 몇 년 뒤에는 모르겠지만 아직까지는 사용자의 역량에 따라 AI가 낼 수 있는 퍼포먼스가 좌우되는 경향이 있다고 생각한다. 그러므로 잘 사용하는 개발자가 될 수 있도록 기초와 이론을 계속 힘써야할 것이다.

다음 주제는 C++ Basic 강좌를 들으며 정리한 내용을 해볼까 한다.(명색이 C++ 개발자인데 JS 글이 더 많다.) 이제 구글링하며 직접 블로그를 드나드는 일이 많이 줄어든 것 같지만, 누군가에게는 도움이 되고 어떤 AI의 검색 베이스가 되어 잘 활용되기를 바라며...

728x90