본문 바로가기

728x90

모던 C++ 디자인 패턴

[디자인패턴][행위패턴] 매개자 Meditator - C++ [모던 C++ 디자인 패턴] 책을 바탕으로 공부하는 내용을 정리한 내용이다. Meditator Pattern 우리가 작성하는 코드의 상당 부분은 서로 다른 컴포넌트(클래스) 간 포인터나 직접적 참조를 통해 커뮤니케이션한다. 어떤 경우 컴포넌트 간 명시적으로 상대방 객체의 존재를 알아야 하는 상황이 불편할 수 있다. 또는 상대방 객체를 알더라도 객체 생성/소멸 시점에 대한 관리 때문에 포인터나 참조로 접근되는 것이 싫을 수 있다. 매개자는 컴포넌트 간 커뮤니케이션을 돕기 위한 메커니즘이다. 매개자 자체는 커뮤니케이션에 동반되는 모든 컴포넌트로부터 접근 가능해야 한다. 즉, 전역 정적 변수이거나 모든 컴포넌트에 참조가 노출되어야 한다. 채팅 룸 채팅 룸은 매개자 디자인 패턴이 적용될 수 있는 가장 전형적인 .. 더보기
[디자인패턴][행위패턴] 반복자 Iterator - C++ [모던 C++ 디자인 패턴] 책을 바탕으로 공부하는 내용을 정리한 내용이다. Iterator Pattern 복잡한 데이터 구조를 다뤄야 할 때 데이터 순회(traversal) 문제에 부딪힌다. 여러 방법이 있지만 vector 형태의 데이터에서는 반복자(iterator)라고 불리는 방법이 흔히 사용된다. 반복자는 단순히 어떤 컬렉션의 항목 하나에 접근하는 방법과 그 항목의 다음 항목으로 이동하는 방법을 알고 있는 것이다. 따라서 ++ 연산자와 != 연산자만 구현하면 된다. C++ 표준 라이브러리에서도 반복자를 광범위하게 사용하고 있다. 먼저 C++ 표준 라이브러리가 반복자를 어떻게 사용하고 있는지 알아볼 것이다. 그다음 직접 반복자를 만들고 반복자가 가진 제약들을 살펴본다. 표준 라이브러리 반복자 vect.. 더보기
[디자인패턴][행위패턴] 인터프리터 Interpreter - C++ [모던 C++ 디자인 패턴] 책을 바탕으로 공부하는 내용을 정리한 내용이다. Interpreter Pattern Interpreter 디자인 패턴의 목적은 입력 데이터를 해석하는 것이다. 꼭 텍스트에 한정되지는 않는다. 인터프리터의 작업을 수행하는 몇 가지 단순한 예를 보여줄 것이다. 일반적인 예는 다음과 같다. 42나 1.234e12와 같은 숫자 리터럴은 바이너리로 저장하면 효율적이다. C++에서는 Boost.LexicalCast와 같은 고급 라이브러리를 사용할 수 있다. C의 API인 atof()를 이용할 수도 있다. 텍스트에서 어떤 패턴을 찾을 때 정규 표현식을 사용하면 편하다. 정규 표현식은 특정 목적을 위한 완전 별개의 언어다. 정규 표현식도 적절히 해석되어야만 한다. CSV, XML, JSON.. 더보기
[디자인패턴][행위패턴] 커맨드 Command - C++ [모던 C++ 디자인 패턴] 책을 바탕으로 공부하는 내용을 정리한 내용이다. Command Pattern 커맨드 패턴은 어떤 객체를 활용할 때 직접 그 객체의 API를 호출해 조작하는 대신, 작업을 어떻게 하라고 명령을 보내는 방식을 제안한다. 여기서 명령은 무엇을 어떻게 하라는 지시가 담긴 클래스 그 이상도 이하도 아니다. 시나리오 은행의 마이너스 통장을 생각해 보자. 마이너스 통장은 잔고와 인출 한도가 있다. 입금과 출금 동작을 수행해야 한다. 이때 모든 입출금 내역을 기록해야 한다고 하자. 또한, 입출금 클래스는 이미 기존에 만들어져 검증되었고 동작 중이어서 수정할 수 없는 상황이다. struct BankAccount { int balance = 0; int overdraft_limit = -500.. 더보기
[디자인패턴][행위패턴] 책임 사슬 Chain of Responsibility - C++ [모던 C++ 디자인 패턴] 책을 바탕으로 공부하는 내용을 정리한 내용이다. Chain of Responsibility 어떤 시스템을 구성하고 있는 여러 개의 서로 다른 컴포넌트들이 어떤 메시지를 역할에 따라 주고받으며 처리할 수 있다. 개념적으로는 구현하기 쉬워 보인다. 어떤 처리를 수행할 담당 컴포넌트의 목록만 있으면 된다. 시나리오 컴퓨터 게임에서 크리처들이 있다고 하자. 공격력과 방어력 두 가지 값을 속성으로 갖는다고 하자. struct Creature { // 생성자와 add(cm); } else { next = cm; } } virtual void handle() { if ( nullptr != next ) { next->handle(); //< 핵심 부분 } } protected: Creat.. 더보기
[디자인패턴][구조패턴] 프록시 Proxy - C++ [모던 C++ 디자인 패턴] 책을 바탕으로 공부하는 내용을 정리한 내용이다. Proxy pattern Decorator 패턴은 객체의 기능을 수정/확장하는 여러 다른 방법들을 제시해준다. Proxy 패턴도 객체의 기능을 수정/확장한다는 목적은 비슷하지만 기존 API 사용 방식을 정확히 동일하게 유지하면서 내부 동작만 다르게 한다는 점이 다르다. Proxy는 API를 일관되게 유지하기 위한 것은 아니다. 같은 API에 대해서 서로 다른 종류의 서로 다른 목적의 완전히 다른 프록시들이 여러 개발자에 의해 만들어질 수 있기 때문이다. 스마트 포인터 가장 단순하면서도 직접적인 프록시 패턴은 스마트 포인터라 할 수 있다. 스마트 포인터는 포인터의 참조 횟수를 관리하고, 몇몇 연산자를 오버라이딩하는 래퍼(wrapp.. 더보기
[디자인패턴][구조패턴] 플라이웨이트 Flyweight - C++ [모던 C++ 디자인 패턴] 책을 바탕으로 공부하는 내용을 정리한 내용이다. Flyweight pattern 플라이웨이트 패턴은 많은 수의 가벼운 임시 객체를 스마트 참조로 사용하는 것을 말하며 그러한 객체들을 플라이웨이트라고 부른다. 종종 토큰, 쿠키라고 부르기도 한다. 플라이웨이트 패턴은 많은 수의 매우 비슷한 객체들이 사용되어야 할 때 메모리 사용량을 절감하는 방법으로서 자주 사용된다. 사용자 이름 대규모 멀티 플레이가 지원되는 온라인 게임을 생각해보자. 중복 이름이 허용된다면, 흔한 이름이 생성될 때마다 중복되는 공간을 낭비하게 된다. 대신에 이름을 한 번만 저장하고 같은 이름을 가진 사용자들은 그 이름을 포인터로 갖게 할 수도 있다. 이것은 적지 않은 메모리 절감이다. 더 나아가 이름을 "성"과.. 더보기
[디자인패턴][구조패턴] 퍼싸드 Facade - C++ [모던 C++ 디자인 패턴] 책을 바탕으로 공부하는 내용을 정리한 내용이다. Facade pattern 퍼싸드(퍼사드)는 프랑스어로 출입구가 있는 건물의 앞부분을 말한다. 이번 패턴은 특이하게 터미널에 대한 이야기를 통해 설명을 진행한다. 먼저 운영 체제에서 제공하는 터미널/콘솔의 CLI와 금융권의 금융 데이터 문자 렌더링은 미묘한 차이가 있따. 터미널은 어떻게 동작할까? 터미널 윈도의 첫 번째 구성 요소는 버퍼다. 버퍼에 렌더링할 문자들이 저장된다. 버퍼는 보통 char/wchar_t 타입의 1차원 또는 2차원 배열로 만들어진다. 버퍼는 보통 현재의 입력 라인을 가리키는 어떤 표시를 갖는다. 그 표시를 이용해 버퍼가 가득 찼을 때, 항상 새로운 라인을 할당하는 것이 아니라 가장 오래된 라인부터 덮어쓰면.. 더보기

728x90