디자인 패턴 소개
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 90번째.
디자인 패턴은 소프트웨어 설계에서 발생하는 일반적인 문제들에 대해 검증되고 재사용 가능한 솔루션입니다. 이는 직접 복사하는 코드가 아니라, 특정 과제를 우아하게 해결하기 위해 클래스와 객체를 구조화하는 방법을 설명하는 템플릿이나 청사진입니다.
이 개념은 23가지 기본 패턴을 정리한 1994년 저서인 "Gang of Four" (GoF)에 의해 대중화되었습니다. 이러한 패턴은 보통 세 가지 범주로 나뉩니다:
| 범주 | 목적 | 예시 |
|---|---|---|
| 생성 (Creational) | 객체 생성 메커니즘 | Singleton, Factory, Builder |
| 구조 (Structural) | 클래스 및 객체 구성 | Adapter, Decorator, Composite |
| 행위 (Behavioral) | 객체 상호작용 및 책임 | Observer, Strategy, Command |
왜 디자인 패턴을 배워야 할까요? 디자인 패턴은 개발자들 사이에서 공통된 어휘를 제공합니다. "여기서 Factory를 사용하자"라고 말하는 것만으로도 복잡한 아이디어를 즉시 전달할 수 있습니다. 또한 솔루션을 재발명하는 것을 방지하고 코드를 더 유연하고 유지 관리하기 쉽게 만들어 줍니다.
C++에서 디자인 패턴은 이미 배운 OOP 기능인 상속, 다형성, 추상 클래스, 그리고 템플릿을 활용합니다. 다음 레슨들에서 여러분은 여러 필수적인 패턴들을 구현하고, 각 패턴이 언제 적절한 도구인지 이해하게 될 것입니다.
챌린지
쉬움세 가지 디자인 패턴 카테고리에 대한 이해를 보여주는 간단한 패턴 분류기를 만들어 보겠습니다. 패턴 이름을 입력받아 해당 패턴이 어떤 카테고리(Creational, Structural, 또는 Behavioral)에 속하는지 식별하고, 해당 카테고리의 목적에 대한 간단한 설명을 제공하는 시스템을 작성하게 됩니다.
코드는 다음 세 개의 파일로 구성됩니다:
PatternCategory.h: 디자인 패턴 카테고리를 나타내는PatternCategory라는 추상 기본 클래스를 정의합니다. 이 클래스는 다음을 포함해야 합니다:- 카테고리 이름을 문자열로 반환하는 순수 가상 메서드
getName() - 해당 카테고리의 패턴이 수행하는 작업에 대한 설명을 반환하는 순수 가상 메서드
getPurpose() - 가상 소멸자
그런 다음
PatternCategory를 상속받는 세 개의 파생 클래스를 만듭니다:CreationalCategory— 이름"Creational"과 목적"Object creation mechanisms"을 반환합니다.StructuralCategory— 이름"Structural"과 목적"Class and object composition"을 반환합니다.BehavioralCategory— 이름"Behavioral"과 목적"Object interaction and responsibility"를 반환합니다.
- 카테고리 이름을 문자열로 반환하는 순수 가상 메서드
PatternClassifier.h: 주어진 패턴이 어떤 카테고리에 속하는지 식별할 수 있는PatternClassifier클래스를 만듭니다.분류기에는 패턴 이름(문자열)을 인자로 받아 적절한
PatternCategory에 대한 포인터를 반환하는classify메서드가 있어야 합니다. 메모리 관리를 위해 스마트 포인터(std::unique_ptr)를 사용하세요.분류기는 다음 패턴들을 인식해야 합니다:
- Creational:
Singleton,Factory,Builder - Structural:
Adapter,Decorator,Composite - Behavioral:
Observer,Strategy,Command
패턴 이름을 인식할 수 없는 경우
nullptr을 반환합니다.- Creational:
main.cpp: 단일 입력으로 디자인 패턴의 이름을 읽습니다.PatternClassifier를 생성하고 이를 사용하여 입력된 패턴을 분류합니다. 패턴이 인식되면 다음과 같이 출력합니다:[PatternName] is a [CategoryName] pattern Purpose: [CategoryPurpose]패턴이 인식되지 않으면 다음과 같이 출력합니다:
Unknown pattern: [PatternName]
예를 들어, 입력이 Singleton인 경우:
Singleton is a Creational pattern
Purpose: Object creation mechanisms입력이 Observer인 경우:
Observer is a Behavioral pattern
Purpose: Object interaction and responsibility입력이 Proxy인 경우:
Unknown pattern: Proxy이 챌린지는 이미 익힌 개념인 상속, 다형성, 스마트 포인터를 연습하면서 디자인 패턴의 세 가지 카테고리를 다시 한번 확인하게 해줍니다. 다중 파일 구조는 실제 프로젝트에서 관련 클래스들을 구성하는 방식을 반영합니다.
치트 시트
디자인 패턴은 일반적인 소프트웨어 설계 문제에 대한 재사용 가능한 해결책입니다. 이는 직접 복사할 코드가 아니라 클래스와 객체를 구조화하기 위한 템플릿 역할을 합니다.
디자인 패턴은 크게 세 가지 범주로 나뉩니다:
| 범주 | 목적 | 예시 |
|---|---|---|
| 생성(Creational) | 객체 생성 메커니즘 | Singleton, Factory, Builder |
| 구조(Structural) | 클래스 및 객체 구성 | Adapter, Decorator, Composite |
| 행위(Behavioral) | 객체 상호작용 및 책임 | Observer, Strategy, Command |
디자인 패턴의 장점:
- 개발자 간의 공통된 어휘 제공
- 일반적인 문제에 대한 해결책을 다시 발명하는 것을 방지
- 코드를 더 유연하고 유지보수하기 쉽게 만듦
C++에서 디자인 패턴은 상속, 다형성, 추상 클래스 및 템플릿을 포함한 OOP 기능을 활용합니다.
직접 해보기
#include <iostream>
#include <string>
#include "PatternClassifier.h"
int main() {
// 패턴 이름을 읽습니다
std::string patternName;
std::cin >> patternName;
// TODO: PatternClassifier 인스턴스를 생성합니다
// TODO: 분류기를 사용하여 입력 패턴을 분류합니다
// TODO: 패턴이 인식되면 다음을 출력합니다:
// "[PatternName] is a [CategoryName] pattern"
// "Purpose: [CategoryPurpose]"
// TODO: 패턴이 인식되지 않으면 (nullptr), 다음을 출력합니다:
// "Unknown pattern: [PatternName]"
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.