반응형
지금까지 우리는 생성, 구조적 패턴들을 모던 C++ 관점에서 재해석하며 상속 계층, 가상 함수 테이블, 복잡한 클래스 증가 대신 Concepts, 람다, 함수 합성, std::expected, std::format, Ranges, std::variant 등을 활용해 더 간결하고 타입 안전하며 유지보수성 높은 코드를 작성할 수 있음을 확인했습니다. 이제는 행동(Behavioral) 패턴으로 넘어가 보겠습니다.행동 패턴은 객체 간의 상호작용, 책임 분배, 알고리즘 캡슐화를 다룹니다. 그 출발점으로 전략(Strategy) 패턴을 선택합니다. 전략 패턴은 알고리즘을 한 객체에 캡슐화하고, 이를 교체함으로써 런타임에 알고리즘을 선택할 수 있게 하는 패턴입니다. 전통적으로는 상속 기반 인터페이스를 통해 구현했지만,..
지난 글에서는 플라이웨이트(Flyweight) 패턴을 모던 C++ 관점에서 재해석하며, 대량의 유사 객체 공유를 std::expected, std::string_view, Ranges, Concepts 등을 사용해 더 안전하고 유지보수성 높은 방식으로 구현할 수 있음을 살펴봤습니다. 이번 글에서는 구조적 패턴의 또 다른 핵심, 프록시(Proxy) 패턴을 다룹니다.프록시 패턴은 특정 객체(Real Subject)에 대한 접근을 제어하거나, 지연 로딩(Lazy Loading), 원격 호출(Remote Proxy), 캐싱(Caching) 등의 부가 기능을 중간에 삽입하는 기법을 제안합니다. 전통적 C++ 구현은 가상 함수를 통한 상속 기반 대리 객체로 접근했지만, 모던 C++20 이상의 기능을 활용하면 함수 ..
앞선 글에서는 브리지(Bridge) 패턴을 통해 모던 C++에서 상속 기반의 전통적 설계를 어떻게 Concepts, 함수 객체, std::variant 등으로 대체하며 더 유연한 구조를 만들 수 있는지 살펴보았습니다. 이번에는 데코레이터(Decorator) 패턴을 재조명합니다.데코레이터 패턴은 객체에 기능을 동적으로 추가하는 방법을 제시합니다. 전통적으로는 상속이나 래핑(wrapper) 클래스를 사용해 "장식(Decoration)"을 더했지만, 모던 C++에서는 람다, std::function, Ranges, Concepts 등의 기능을 활용해 상속 계층 폭발을 줄이고, 훨씬 간결하고 가독성 높은 코드로 기능을 확장할 수 있습니다.패턴 소개: 데코레이터(Decorator)의도:객체에 추가 책임(기능)을 ..
이전 글에서는 추상 팩토리(Abstract Factory) 패턴을 모던 C++로 재해석하며, 상속 기반의 전통적 구현 방식이 어떻게 Concepts, std::expected, std::variant 등을 활용해 보다 탄탄하고 유연한 구조로 바뀔 수 있는지 알아보았습니다. 이번에는 브리지(Bridge) 패턴에 주목합니다.브리지 패턴의 핵심 의도는 "추상(Abstraction)과 구현(Implementation)을 분리하여 둘을 독립적으로 확장할 수 있게 하는 것"입니다. 전통적인 C++ 구현에서는 추상 클래스 계층과 구현 클래스 계층을 상속으로 연결하는 경향이 많았으나, 모던 C++에서는 Concepts, 컴포지션(합성), std::function, 그리고 Ranges나 람다를 통한 파이프라인형 사고로 ..
이전 글에서는 빌더(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 클래스를 상속해 구현했지만, 이는 알고리즘 추가..
이전 글까지 우리는 대부분의 GoF 패턴을 모던 C++ 관점에서 재해석해왔습니다. 이번에는 행동(Behavioral) 패턴 중 아직 다루지 않은 책임 연쇄(Chain of Responsibility) 패턴에 주목합니다.책임 연쇄 패턴은 한 요청이 처리될 수 있는 핸들러를 체인 형태로 연결하고, 요청이 들어오면 체인을 따라가며 처리 가능 한 핸들러를 찾는 구조를 만듭니다. 전통적으로는 핸들러 인터페이스와, setNextHandler() 메서드를 통해 다음 핸들러를 연결하는 구조를 취했지만, 이는 상속 기반 설계로 인한 클래스 증가와 유지보수 어려움을 야기합니다.C++20 이상에서는 Concepts로 요청/응답 인터페이스를 제약하고, 람다와 함수 합성으로 핸들러를 정의해 상속 없이 체인을 구성할 수 있습니다..
이전 글에서는 플라이웨이트(Flyweight) 패턴을 모던 C++ 관점에서 재해석하며, 상속 없이 값 기반 공유 로직을 단순히 구현하고, 조건부 처리, 비동기 로딩, 로깅, 에러 처리 등 다양한 요구에도 쉽게 대응할 수 있음을 확인했습니다. 이번에는 구조적 패턴 중 프록시(Proxy) 패턴을 다룹니다.프록시 패턴은 객체 접근을 제어하거나, 지연 로딩(Lazy Loading), 원격 호출(Remote Proxy), 캐싱(Caching), 권한 체크 등의 기능을 대리 객체를 통해 투명하게 추가하는 패턴입니다. 전통적으로는 상속 기반 인터페이스와 Proxy 클래스를 정의해 접근 로직을 구현했으나, 이는 클래스 증가, 유지보수 어려움, 에러 처리나 비동기 처리 시 복잡성을 초래합니다.C++20 이상에서는 Con..