반응형
이전 글에서는 전략(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로 요청/응답 인터페이스를 제약하고, 람다와 함수 합성으로 핸들러를 정의해 상속 없이 체인을 구성할 수 있습니다..
이전 글에서는 플라이웨이트(Flyweight) 패턴을 모던 C++ 관점에서 재해석하며, 상속 없이 값 기반 공유 로직을 단순히 구현하고, 조건부 처리, 비동기 로딩, 로깅, 에러 처리 등 다양한 요구에도 쉽게 대응할 수 있음을 확인했습니다. 이번에는 구조적 패턴 중 프록시(Proxy) 패턴을 다룹니다.프록시 패턴은 객체 접근을 제어하거나, 지연 로딩(Lazy Loading), 원격 호출(Remote Proxy), 캐싱(Caching), 권한 체크 등의 기능을 대리 객체를 통해 투명하게 추가하는 패턴입니다. 전통적으로는 상속 기반 인터페이스와 Proxy 클래스를 정의해 접근 로직을 구현했으나, 이는 클래스 증가, 유지보수 어려움, 에러 처리나 비동기 처리 시 복잡성을 초래합니다.C++20 이상에서는 Con..
지금까지 우리는 C++ 코드 스타일에 대한 다양한 관점을 주제별로 살펴보았습니다. 들여쓰기와 공백 규칙, 네이밍 컨벤션, 헤더 파일 구조, 클래스와 함수 인터페이스, 주석과 문서화, 템플릿과 메타프로그래밍, 예외 처리와 에러 관리, 현대 문법 사용법, I/O와 문자열 처리, 빌드 시스템과 모듈에 이르기까지 폭넓은 분야를 다루었습니다.각 편에서 특정 스타일 가이드(예: 구글 C++ 스타일 가이드, LLVM 스타일 가이드, 모질라 스타일 가이드)를 언급하고, 다양한 선택지와 그 장단점, 상황별 적합도를 논해보았습니다. 이제 이 시리즈를 마무리하며, "정답"이 없는 스타일 문제에서 어떻게 팀 합의와 문서화를 통해 최선의 균형을 찾을 수 있는지 정리해보겠습니다.정답은 없다, 하지만 일관성은 있다C++ 코드 스타..
C++20의 std::format 도입으로 문자열 포매팅이 한층 편리해졌습니다. 이전에는 printf 계열 함수나 iostream 기반의 이번 글에서는 구글 C++ 스타일 가이드, LLVM 스타일 가이드, 모질라 스타일 가이드 등 다양한 가이드에서 제안하는 I/O 스타일, 문자열 처리 방식, 로깅 규칙을 살펴보며, 상황에 따라 어떤 접근이 적합한지 논의합니다.다양한 스타일 가이드의 접근구글 C++ 스타일 가이드:iostream 사용에 신중. 복잡한 I/O 로직은 명시적 함수 사용 권장std::string_view 활용을 통해 함수 인자로 문자열을 넘길 때 복사 최소화로깅 시 가독성 높은 메시지 포맷, 필요 시 std::format 기반 형식 지정 가능LLVM 스타일 가이드:iostream 사용 가능하지만..
C++11 이후로 언어에 다양한 현대 문법 요소가 추가되어 개발자들의 표현력을 풍부하게 해주었습니다. auto 타입 추론, 구조적 바인딩, 람다 캡처 개선, range-based for 루프 등은 코드 가독성, 유지보수성을 높이는 강력한 도구입니다. 하지만 이 도구들을 어떻게 스타일 있게 사용하는지는 여전히 논란이 될 수 있습니다. 적절히 사용하면 코드를 간결하고 직관적으로 만들지만, 남용하면 타입 정보를 숨겨 가독성을 해칠 수 있습니다.이번 글에서는 구글 C++ 스타일 가이드, LLVM 스타일 가이드, 모질라 스타일 가이드 등에서 현대 문법 요소 사용 관련 조언을 살펴보고, 상황에 따라 어떤 방식을 권장하는지, 장단점을 비교해봅니다.다양한 스타일 가이드의 접근구글 C++ 스타일 가이드:auto는 타입이..
C++에서 예외(exception)는 런타임 오류를 처리하는 핵심 메커니즘이지만, 모든 코드베이스가 예외를 선호하는 것은 아닙니다. 일부 프로젝트는 성능상 이유나 제약 때문에 예외를 비활성화하고, 에러 코드를 반환하거나 std::expected를 통한 명시적 에러 처리 방식을 선호하기도 합니다. 또한 RAII를 통해 예외 안전성을 확보하고, 리소스 누수를 방지하는 패턴도 중요한 스타일 이슈입니다.이번 글에서는 다양한 스타일 가이드와 프로젝트 사례를 바탕으로, 예외 사용 여부 결정, std::expected나 에러 코드 기반 접근, RAII 기법, noexcept 사용, 그리고 에러 처리 시 주석과 문서화 방법 등을 다뤄봅니다.다양한 스타일 가이드와 사례구글 C++ 스타일 가이드:과거에는 예외 사용을 금지..
C++ 템플릿과 메타프로그래밍은 코드 재사용성과 추상화의 강력한 수단이지만, 복잡하고 장황해지기 쉽습니다. C++20 Concepts를 도입함으로써 타입 제약을 명확히 표현할 수 있지만, 이 또한 스타일 유지에 도전 과제를 던집니다. 템플릿 파라미터 리스트의 길고 난해한 선언, SFINAE를 통한 조건부 활성화 코드, 개별 trait 구조체나 헬퍼 템플릿의 무질서한 배치 등은 코드 가독성을 해칠 수 있습니다.이번 글에서는 구글 C++ 스타일 가이드, LLVM 스타일 가이드, 모질라 스타일 가이드 등에서 언급하는 템플릿 및 메타프로그래밍 관련 스타일 이슈를 살펴봅니다. 또한 Concepts를 활용하는 방법, SFINAE 대신 Concepts를 사용하는 접근, 템플릿 파라미터 정렬, trait 정의 분리, ..