C++/개념정리

C++[디자인 패턴]

jeongchanhyo 2025. 1. 6. 20:36

디자인 패턴이란?

소프트웨어 설계에서 자주 발생하는 문제를 해결하기 위한 일반적인 솔루션이다.

이를 크게 생성 패턴, 구조 패턴, 행동 패턴으로 나눌 수 있다.

생성 패턴 (Creational Patterns)

생성 패턴은 객체 생성 메커니즘을 다루어, 객체 생성의 복잡성을 줄이고 코드의 유연성을 높이는 데 도움을 줍니다. 주요 생성 패턴은 다음과 같다.

  • 싱글톤 패턴 (Singleton Pattern): 클래스의 인스턴스를 하나만 생성하고, 이 인스턴스에 대한 전역 접근을 제공.
    • 애플리케이션에서 설정이나 로그 기록을 관리하는 클래스는 보통 싱글톤으로 구현. 이렇게하면 여러곳에서 설정을 공유할 수 있어 사용자가 매번 새로운 설정을 할 필요없어서 좋다.
  • 팩토리 메소드 패턴 (Factory Method Pattern): 객체 생성의 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지는 서브클래스에서 결정하도록 함.
    • 자동차를 만드는 공장에서는 여러 종류의 자동차(세단, SUV 등)를 생산할 수 있습니다. 각 자동차는 팩토리 메소드를 통해 생성.
  • 추상 팩토리 패턴 (Abstract Factory Pattern): 관련된 객체들의 집합을 생성하는 인터페이스를 제공하며, 구체적인 클래스는 서브클래스에서 결정.
    • UI 라이브러리에서 버튼, 텍스트박스 등의 위젯을 생성할 때, 운영체제(Windows, macOS)에 따라 다른 스타일의 위젯을 생성할 수 있다.
  • 빌더 패턴 (Builder Pattern): 복잡한 객체를 단계별로 생성할 수 있도록 하여, 객체의 생성 과정을 분리.
    • 피자를 주문할 때, 도우의 종류, 토핑, 크기 등을 선택하여 최종적으로 원하는 피자를 만드는 과정과 유사하다고 보면된다. 서브웨이스타일 느낌이 필요할 때 좋은 패턴.
  • 프로토타입 패턴 (Prototype Pattern): 기존 객체를 복제하여 새로운 객체를 생성하는 방법을 제공.
    • 게임에서 캐릭터를 복제하여 새로운 캐릭터를 만들 때, 기존 캐릭터의 속성을 복사하여 새로운 캐릭터를 생성하는 방식.

구조 패턴 (Structural Patterns)

구조 패턴은 클래스와 객체의 조합을 다루어, 복잡한 구조를 단순화하고 유연성을 높인다. 

  • 어댑터 패턴 (Adapter Pattern): 서로 호환되지 않는 인터페이스를 가진 클래스들을 연결해주는 역할을 합니다.
      • 전기 어댑터처럼, 다른 나라의 플러그를 자신의 콘센트에 맞게 변환해주는 경우를 생각할 수 있다. 예를 들어, USB-C 포트를 가진 기기를 일반 USB 포트에 연결할 수 있도록 해준다.
  • 브리지 패턴 (Bridge Pattern): 구현부에서 독립적으로 추상화를 변경할 수 있도록 해준다.
    • TV 리모컨과 TV의 종류를 생각해보면, 리모컨은 다양한 TV 모델을 제어할 수 있지만, 각 모델의 구현은 다를 수 있다. 리모컨(추상화)과 TV(구현)를 분리하여 서로 영향을 주지 않도록 함.
  • 컴포지트 패턴 (Composite Pattern): 객체를 트리 구조로 구성하여 부분-전체 계층을 표현.
    • 파일 시스템을 생각해보세요. 파일(개별 객체)과 폴더(복합 객체)를 동일하게 다룰 수 있다. 폴더 안에 여러 파일과 다른 폴더가 있을 수 있으며, 클라이언트는 이들을 동일하게 처리.
  • 데코레이터 패턴 (Decorator Pattern): 객체에 추가적인 기능을 동적으로 부여할 수 있도록 해줌.
    • 커피에 우유, 설탕 등을 추가하는 경우를 생각해보면, 기본 커피 객체에 데코레이터를 추가하여 다양한 맛을 만들 수 있다.
  • 파사드 패턴 (Facade Pattern): 복잡한 서브시스템에 대한 간단한 인터페이스를 제공합니다.
    • 홈 시어터 시스템을 생각해보세요. 여러 장치(프로젝터, 스피커, 블루레이 플레이어 등)를 간단한 버튼 클릭으로 제어할 수 있도록 하는 퍼사드 클래스를 만들 수 있습니다.
  • 플라이웨이트 패턴 (Flyweight Pattern): 많은 수의 객체를 효율적으로 공유하여 메모리 사용을 줄입니다.
    • 게임에서 많은 나무 객체를 생성할 때, 나무의 속성(색상, 종류 등)을 공유하여 메모리 사용량을 줄이는 방식.
  • 프록시 패턴 (Proxy Pattern): 다른 객체에 대한 접근을 제어하는 대리 객체를 제공.
    • 이미지 로딩 시, 실제 이미지를 로드하기 전에 프록시 객체를 사용하여 로드가 필요한지 여부를 판단할 수 있습니다. 이로 인해 성능을 최적화할 수 있다.

행동 패턴 (Behavioral Patterns)

행동 패턴은 객체 간의 상호작용과 책임 분배를 다룬다.

  • 책임 연쇄 패턴 (Chain of Responsibility Pattern): 요청을 처리할 수 있는 객체의 체인을 구성하여, 요청을 처리할 수 있는 객체가 처리하도록 합니다.
    • 고객 서비스 센터에서 문의가 들어오면, 먼저 상담원, 그 다음 관리자, 마지막으로 전문 부서로 전달되는 방식입니다.
  • 커맨드 패턴 (Command Pattern): 요청을 객체로 캡슐화하여, 요청의 매개변수화, 큐잉, 로깅 등을 가능하게 합니다.
    • 리모컨의 버튼을 누르면 특정 동작(예: TV 켜기, 볼륨 조절)이 실행됩니다. 각 버튼 클릭은 커맨드 객체로 캡슐화됩니다.
  • 인터프리터 패턴 (Interpreter Pattern): 언어의 문법을 정의하고, 해당 문법을 해석하는 클래스를 제공합니다.
    • 리스트, 배열 같은 데이터 구조에서 요소를 하나씩 접근할 수 있는 방법을 제공합니다. 예를 들어, 책 목록을 순회하며 각 책의 제목을 출력하는 경우입니다.
  • 이터레이터 패턴 (Iterator Pattern): 컬렉션의 내부 구조를 노출하지 않고도 그 컬렉션의 요소에 접근할 수 있도록 해줍니다.
    • 리스트, 배열 같은 데이터 구조에서 요소를 하나씩 접근할 수 있는 방법을 제공합니다. 예를 들어, 책 목록을 순회하며 각 책의 제목을 출력하는 경우입니다.
  • 옵저버 패턴 (Observer Pattern): 한 객체의 상태 변화에 따라 다른 객체에게 자동으로 통지하는 방법을 제공합니다.
    • 주식 시장에서 주식 가격이 변동할 때, 이를 구독한 투자자에게 자동으로 알림을 보내는 경우입니다.
  • 상태 패턴 (State Pattern): 객체의 상태에 따라 행동을 변경할 수 있도록 합니다.
    • 게임 캐릭터가 "정상", "부상", "사망" 상태에 따라 행동(이동, 공격 등)을 다르게 하는 경우입니다.
  • 전략 패턴 (Strategy Pattern): 알고리즘을 정의하고, 이를 캡슐화하여 서로 교환 가능하게 만들어줍니다.
    • 다양한 정렬 알고리즘(버블 정렬, 퀵 정렬 등)을 제공하고, 필요에 따라 원하는 정렬 알고리즘을 선택하여 사용할 수 있는 경우입니다.
  • 템플릿 메소드 패턴 (Template Method Pattern): 알고리즘의 구조를 정의하고, 서브클래스에서 구체적인 구현을 제공합니다.
    • 요리 레시피를 생각해보세요. 기본적인 요리 과정은 동일하지만, 재료나 조리 방법은 각 요리에 따라 다를 수 있습니다.

'C++ > 개념정리' 카테고리의 다른 글

개념정리[연산자(&*)]  (0) 2025.02.07
C++[코드변경 깃허브 적용]  (0) 2025.01.13
C++[SOLID 원칙]  (0) 2025.01.03
C++[응집도, 결합도]  (0) 2025.01.03
C++[sort알고리즘]  (0) 2025.01.02