반응형
이전 글에서는 메멘토(Memento) 패턴을 모던 C++ 관점에서 재해석하며, 상속 없이 값 기반 상태 스냅샷과 std::expected, coroutine, Ranges 등을 활용해 Undo/Redo, 비동기 복원, 로깅 등의 요구사항에 대응할 수 있음을 확인했습니다. 이번에는 행동(Behavioral) 패턴 중 템플릿 메서드(Template Method) 패턴을 다룹니다.템플릿 메서드 패턴은 상위 클래스에서 알고리즘의 골격(템플릿)을 정의하고, 하위 클래스에서 일부 단계를 오버라이드하여 구체화하는 패턴입니다. 그러나 전통적 접근은 상속 기반 구조로, 알고리즘 변형 시 하위 클래스 증가, 유지보수 어려움 등이 발생합니다. C++20 이상에서는 Concepts, 람다, std::expected, std:..
이전 글에서는 미디에이터(Mediator) 패턴을 모던 C++ 관점에서 재해석하며, 상속 기반 구조 없이도 Concepts, std::function, std::expected, coroutine, Ranges 등을 활용해 객체 간 상호작용을 유연하고 타입 안전하게 구현할 수 있음을 확인했습니다. 이번에는 행동(Behavioral) 패턴 중 메멘토(Memento) 패턴을 다룹니다.메멘토 패턴은 객체 상태를 캡슐화(스냅샷)하여, 이후 필요할 때 원래 상태로 복원하는 기법을 제공합니다. 전통적으로는 Originator(원본 객체), Memento(상태 저장), Caretaker(메멘토 관리) 클래스를 정의하고, Memento 클래스로 상태를 저장/복원하는 상속 기반 구조를 사용했습니다. 그러나 모던 C++2..
이전 글에서는 이터레이터(Iterator) 패턴을 모던 C++ 관점에서 재해석하며, C++20 Ranges와 Concepts를 통해 상속 없이도 선언적이고 타입 안전한 순회 방식을 구현할 수 있음을 확인했습니다. 이번에는 행동(Behavioral) 패턴 중 미디에이터(Mediator) 패턴을 다룹니다.미디에이터 패턴은 객체들이 서로 직접 통신하는 대신, 미디에이터(중재자)를 통해 상호작용하도록 하여 객체 간 결합을 느슨하게 만드는 패턴입니다. 전통적으로는 미디에이터 인터페이스와 구체 미디에이터를 상속 기반으로 정의하고, 각 객체가 미디에이터를 참조해 메시지나 이벤트를 중개하는 구조를 사용했습니다. 그러나 모던 C++20 이상에서는 Concepts, 람다, std::function, std::expecte..
이전 글에서는 인터프리터(Interpreter) 패턴을 모던 C++ 관점에서 재해석하며, 상속 기반 Expression 클래스 계층 없이도 std::variant, std::visit, Concepts, std::expected, Ranges, coroutine 등을 활용해 언어 해석 로직을 단순하고 확장성 높게 구현할 수 있음을 확인했습니다. 이번 글에서는 행동(Behavioral) 패턴 중 이터레이터(Iterator) 패턴을 다룹니다.이터레이터 패턴은 컬렉션의 내부 표현을 노출하지 않고, 요소에 접근하는 통일된 인터페이스를 제공하는 패턴입니다. 전통적으로는 컬렉션 별로 Iterator 인터페이스를 정의하고, begin()/end() 또는 next(), hasNext() 등의 메서드를 통해 요소 순회가..
이전 글에서는 커맨드(Command) 패턴을 모던 C++20 이상 관점에서 재해석하며, 상속 기반 명령 클래스 대신 람다, Concepts, std::function, std::expected, coroutine, Ranges, std::format 등을 활용해 더 간결하고 확장성 높은 명령 시스템을 구현하는 방법을 살펴보았습니다. 이번 글에서는 행동(Behavioral) 패턴 중 인터프리터(Interpreter) 패턴을 다룹니다.인터프리터 패턴은 언어(DSL, 간단한 명령어 집합)나 표현(Expression)을 해석하는 로직을 객체로 캡슐화하는 패턴입니다. 전통적으로는 상속 기반 Expression 인터페이스, 각각의 구체 표현 클래스(NonterminalExpression, TerminalExpres..
커맨드(Command) 패턴은 실행할 작업(명령)을 객체로 캡슐화하여, 명령을 매개변수로 전달하거나 큐잉, Undo/Redo, 비동기 실행 등의 기능을 가능하게 하는 중요한 패턴입니다. 하지만 전통적 구현(특히 C++98/03, 심지어 C++11/14/17 시절)에서는 다음과 같은 단점이 있었습니다.전통적 방식:추상 커맨드 인터페이스(abstract Command) 정의이를 상속하는 구체 커맨드 클래스 다수 정의 → 클래스 수 증가, 유지보수성 저하Undo/Redo, 비동기 처리, 로깅 추가 시 복잡성 폭발명령 교체, 에러 처리 등 구현이 번거로움하지만, C++20 이상 모던 C++에서는 람다, std::function, Concepts, std::expected, std::format, coroutin..
이전 글에서는 상태(State) 패턴을 모던 C++ 관점에서 재해석하며, 상속 기반 상태 클래스와 vtable에 의존하지 않고 std::variant, std::visit, Concepts, std::expected, std::format, Coroutines 등을 활용해 더 선언적이고 유지보수성 높은 상태 전이 로직을 구현할 수 있음을 확인했습니다. 이번에는 행동(Behavioral) 패턴 중 책임 연쇄(Chain of Responsibility) 패턴을 다룹니다.책임 연쇄 패턴은 요청(request)이 처리될 수 있는 핸들러(handler)들을 체인 형태로 연결하고, 각 핸들러가 요청을 처리하거나 다음 핸들러로 넘기는 구조를 제안합니다. 전통적으로는 상속 기반 핸들러 클래스 계층을 정의하고, setN..
이전 글에서는 옵저버(Observer) 패턴을 모던 C++ 관점에서 재해석하며, 상속 기반 인터페이스 대신 람다, std::function, std::expected, Ranges, 코루틴 등을 활용해 더욱 유연하고 타입 안전하며 이벤트 중심적인 구조를 구현할 수 있음을 확인했습니다. 이번에는 행동(Behavioral) 패턴 중 또 하나의 대표 주자인 상태(State) 패턴에 주목합니다.상태 패턴은 객체가 내부 상태에 따라 다른 행동을 하도록 하며, 상태 전이를 명확하게 표현하는 패턴입니다. 전통적으로는 상속 기반 상태 클래스와 가상 함수를 통해 상태 변화를 구현했지만, 모던 C++20 이상에서는 std::variant, std::visit, Concepts, 그리고 코루틴(coroutines) 등을 활..
지난 글에서는 전략(Strategy) 패턴을 모던 C++ 관점에서 재해석하며, 상속과 가상 함수를 통한 고전적 접근 대신 Concepts, 람다, std::function, std::expected, std::format 등 현대적 언어 기능을 활용해 상속 없이도 유연한 알고리즘 선택을 구현할 수 있음을 확인했습니다. 이번 글에서는 행동(Behavioral) 패턴 중 또 하나의 대표 주자인 옵저버(Observer) 패턴을 다룹니다.옵저버 패턴은 객체 간의 1:N 의존성을 정의해, 한 객체의 상태 변화 시 이를 의존하는 다른 객체(옵저버)에게 자동으로 통지하는 패턴입니다. 전통적으로는 "Subject가 Observer 리스트를 관리"하고 "상속 기반의 Update() 가상 함수 호출"을 통해 알림을 전달했..
지금까지 우리는 생성, 구조적 패턴들을 모던 C++ 관점에서 재해석하며 상속 계층, 가상 함수 테이블, 복잡한 클래스 증가 대신 Concepts, 람다, 함수 합성, std::expected, std::format, Ranges, std::variant 등을 활용해 더 간결하고 타입 안전하며 유지보수성 높은 코드를 작성할 수 있음을 확인했습니다. 이제는 행동(Behavioral) 패턴으로 넘어가 보겠습니다.행동 패턴은 객체 간의 상호작용, 책임 분배, 알고리즘 캡슐화를 다룹니다. 그 출발점으로 전략(Strategy) 패턴을 선택합니다. 전략 패턴은 알고리즘을 한 객체에 캡슐화하고, 이를 교체함으로써 런타임에 알고리즘을 선택할 수 있게 하는 패턴입니다. 전통적으로는 상속 기반 인터페이스를 통해 구현했지만,..