반응형
지난 글에서는 싱글톤(Singleton) 패턴을 모던 C++ 관점에서 재조명하며, 전역 상태 관리와 초기화 안정성, 에러 처리 측면에서 어떤 개선이 가능한지를 살펴보았습니다. 이번 글에서는 팩토리 메서드(Factory Method) 패턴에 주목합니다. 팩토리 메서드는 인스턴스 생성 로직을 서브클래스나 별도 함수로 위임함으로써, 객체 생성 과정을 캡슐화하고, 클라이언트 코드는 구체적인 클래스에 종속되지 않도록 하는 패턴입니다.고전적 C++에서는 가상 함수 기반 인터페이스를 통해 팩토리 메서드 패턴을 구현했으나, 모던 C++에서는 Concepts를 통해 인터페이스 요구사항을 더 명확히 표현할 수 있습니다. 또한 std::optional, std::expected, std::variant 등을 활용해 생성 실..
이전 글에서 시리즈의 개요를 살펴보았고, 이번에는 GoF 디자인 패턴 중 하나인 싱글톤(Singleton) 패턴을 다룹니다. 싱글톤 패턴은 "프로그램 전역에서 단 하나의 인스턴스만 존재하며, 어디서든 접근 가능한 객체"를 보장하는 설계 기법입니다.전통적 C++(C++98/03) 환경에서 싱글톤 구현은 멀티스레드 안전성, 초기화 시점 관리, 전역 상태로 인한 테스트 난이도 등의 문제로 유명했습니다. C++11 이후 표준에서 정적 지역 변수 초기화의 스레드 안전 보장, std::call_once 등의 도구가 등장하면서 구현 난이도가 감소했지만, 여전히 싱글톤은 "전역 상태"를 갖는다는 본질적 단점을 완전히 해결하지는 못했습니다.모던 C++20 이상의 기능을 활용하면 어떤 측면이 더 개선될 수 있을까요? 이번..
C++20 이상의 모던 C++ 언어 기능들은 개발자들에게 이전에는 상상하기 어려웠던 수준의 표현력, 안전성, 유지보수성을 제공합니다. 한편, 소프트웨어 개발의 전통적인 지식인 “디자인 패턴(Design Patterns)”은 여전히 유지보수성과 확장성이 요구되는 대규모 코드베이스에서 널리 활용되는 개념입니다.이 시리즈에서는 고전적인 GoF(Gang of Four) 디자인 패턴들을 모던 C++ 스타일로 재구현하며, 기존 C++11/14/17 시대의 구현 방식과 비교 분석할 것입니다. 이를 통해 독자들은 각 패턴의 본질을 재확인하는 동시에, Concepts, Ranges, Coroutines, std::format, std::expected, std::jthread, std::variant, std::stri..
이전 글에서는 팩토리 메서드(Factory Method) 패턴을 모던 C++ 관점에서 재해석하며, 상속 없이도 람다와 Concepts, std::expected, coroutine, Ranges, std::format 등을 활용해 객체 생성 로직을 유연하게 교체할 수 있음을 확인했습니다. 이제는 생성(Creational) 패턴 중 프로토타입(Prototype) 패턴을 다룹니다.프로토타입 패턴은 기존 객체를 "복제(Clone)"하는 방식으로 새로운 객체를 생성하는 패턴입니다. 전통적으로는 Prototype 인터페이스와 Clone 메서드를 정의하고, 각 구체 클래스에서 Clone을 오버라이드하는 상속 기반 구조를 사용했습니다. 그러나 이는 새로운 클래스 추가 시 코드 증가, 다양한 복제 로직 추가나 비동기 ..
이전 글에서는 빌더(Builder) 패턴을 모던 C++ 관점에서 재해석하며, 상속 없이 람다, Concepts, std::expected, coroutine, Ranges, std::format 등을 활용해 단계별 객체 생성 과정을 간결히 표현하고, 조건부 단계, 비동기 처리, 로깅, 에러 처리 등 다양한 요구사항을 손쉽게 처리할 수 있음을 확인했습니다. 이제는 생성(Creational) 패턴 중 팩토리 메서드(Factory Method) 패턴을 다룹니다.팩토리 메서드 패턴은 객체 생성 로직을 서브클래스(또는 별도의 로직)로 위임하여, 상위 클래스가 어떤 객체를 생성할지 모르지만, 하위 클래스나 제공된 로직에 따라 객체를 생성하는 패턴입니다. 전통적으로는 Factory Method를 오버라이드하는 하위 ..
이전 글에서는 추상 팩토리(Abstract Factory) 패턴을 모던 C++ 관점에서 재해석하며, 상속 없이도 Concepts, 람다, std::expected, coroutine, Ranges, std::format 등을 활용해 다양한 제품군 생성 로직을 유연하게 구현할 수 있음을 확인했습니다. 이번에는 생성(Creational) 패턴 중 빌더(Builder) 패턴을 다룹니다.빌더 패턴은 복잡한 객체를 단계별로 생성하기 위한 패턴으로, 전통적으로는 Builder 인터페이스와 구체 빌더, 그리고 Director 클래스를 통해 생성 과정과 제품 구성을 분리했습니다. 그러나 이는 클래스 증가, 유지보수 어려움, 에러 처리나 비동기 처리, 조건부 단계 추가 등 다양한 요구사항에 대응하기 어렵습니다.C++20..
이전 글에서는 전략(Strategy) 패턴을 모던 C++ 관점에서 재해석하며, 상속 없이도 람다와 Concepts, std::expected, coroutine, Ranges, std::format 등을 활용해 알고리즘(전략)을 런타임에 교체 가능하게 하고, 비동기 처리나 로깅, 조건부 선택 등 다양한 상황에 쉽게 대응할 수 있음을 확인했습니다. 이번에는 Creational(생성) 패턴 중 하나인 추상 팩토리(Abstract Factory) 패턴을 다룹니다.추상 팩토리 패턴은 관련된 여러 객체(제품)들을 묶어 "제품군(family)"을 생성하는 인터페이스를 제공하는 패턴입니다. 전통적으로는 AbstractFactory 인터페이스와 구체 팩토리 클래스를 상속으로 정의하고, 각 제품(객체) 생성 메서드를 오..
이전 글에서는 상태(State) 패턴을 모던 C++ 관점에서 재해석하며, std::variant, std::visit, Concepts, std::expected, coroutine, Ranges, std::format 등을 활용해 상속 없이 값 기반 상태 머신을 구현하고, 조건부 전이, Undo/Redo, 비동기 처리, 로깅 등 다양한 요구사항에도 대응할 수 있음을 확인했습니다. 이제는 행동(Behavioral) 패턴 중 전략(Strategy) 패턴을 다룹니다.전략 패턴은 알고리즘 패밀리를 정의하고, 이를 교체 가능하게 하여 런타임에 다른 알고리즘을 선택할 수 있도록 하는 패턴입니다. 전통적으로는 Strategy 인터페이스와 ConcreteStrategy 클래스를 상속해 구현했지만, 이는 알고리즘 추가..
이전 글에서는 책임 연쇄(Chain of Responsibility) 패턴을 모던 C++ 관점에서 재해석하며, 상속 없이 람다와 함수 합성, std::expected, coroutine, Ranges, std::format 등을 활용해 요청 처리 파이프라인을 단순하고 유연하게 구현할 수 있음을 확인했습니다. 이제는 행동(Behavioral) 패턴 중 상태(State) 패턴을 다룹니다.상태 패턴은 객체가 내부 상태에 따라 서로 다른 행동을 수행하도록 하는 패턴입니다. 전통적으로는 State 인터페이스, ConcreteState 클래스를 상속해 상태별로 다른 메서드를 오버라이드하고, 상태 전이 시 상태 객체 교체 방식으로 구현했습니다. 이는 새로운 상태 추가 시 클래스 증가, 상태 전이 로직 분산, 유지보수..
이전 글까지 우리는 대부분의 GoF 패턴을 모던 C++ 관점에서 재해석해왔습니다. 이번에는 행동(Behavioral) 패턴 중 아직 다루지 않은 책임 연쇄(Chain of Responsibility) 패턴에 주목합니다.책임 연쇄 패턴은 한 요청이 처리될 수 있는 핸들러를 체인 형태로 연결하고, 요청이 들어오면 체인을 따라가며 처리 가능 한 핸들러를 찾는 구조를 만듭니다. 전통적으로는 핸들러 인터페이스와, setNextHandler() 메서드를 통해 다음 핸들러를 연결하는 구조를 취했지만, 이는 상속 기반 설계로 인한 클래스 증가와 유지보수 어려움을 야기합니다.C++20 이상에서는 Concepts로 요청/응답 인터페이스를 제약하고, 람다와 함수 합성으로 핸들러를 정의해 상속 없이 체인을 구성할 수 있습니다..