Visitor Pattern (방문자 패턴)목적 객체의 속성과 처리(연산)를 분리함으로써 클래스를 수정하지 않고 새로운 연산을 추가할 수 있다. MVC패턴에서 Model과 View를 나눠 놓은것과 비슷하다. UML상에서 Element은 Model과 매핑되고 Visitor는 Controller에 매핑된다. Element에서 Visitor를 accept했을 자기 자신을 Visitor의 visit메소드로 전달 해주는 구조이다. 사용 시나리오 변수 a와 b를 가지고 있는 Element가 있다고 가정한다. Element의 수정없이 더하기 연산과 곱하기 연산을 추가한다. [Element] class Element { public: virtual ~Element(){}; virtual void accept(Visit..
State Pattern (상태 패턴)목적 객체(Context)가 가질 수 있는 (유한한)상태를 추상화하여 런타임에 상태를 유연하게 변경하도록 한다. UML상 전략패턴과 거의 동일하지만 실제로 다른점은 전략패턴의 경우 사용하는 쪽에서 직접 알고리즘을 교체하지만 상태패턴은 사용하는 쪽에서 내부의 상태가 어떻게 바뀌는지 모른다. FSM(Finite State Machine)을 구현하기에 적합한 패턴이다. 사용 시나리오 전구 상태를 표현하는 시스템이 있다. 전구의 상태는 켜짐과 꺼짐 두개가 존재하며 on/off 버튼을 통해 상태가 변한다. 꺼진 상태 -> on 버튼 -> 켜짐 -> on 버튼 -> 동작 안함 켜진 상태 -> off 버튼 -> 꺼짐 -> off 버튼 -> 동작 안함 [Context] class ..
Memento Pattern (메멘토 패턴) 목적 캡슐화를 위배하지 않은 채 객체의 내부 상태를 저장하고 되돌아올 수 있도록 한다. 사용 시나리오 텍스트 에디터를 개발중에 있다고 가정하자 텍스트 에디터에 ctrl Z입력시 이전에 입력했던 텍스트로 상태를 불러오는 기능을 추가한다. [Memento] class InputMemento { public: InputMemento(string& input) { this->input = input; } string getState() { return this->input; } private: string input; }; [Originator] class InputOriginator { public: void setCurrentInput(string input) {..
Mediator Pattern (중재자 패턴) 목적 각각의 객체들(colleague)끼리 서로를 직접 참조하지 않고 mediator(중재자)를 통해 메세지를 주고 받는다. 각각의 객체들은 서로에 대한 정보는 전혀 모르기 때문에 커플링이 느슨하게 한다. 사용 시나리오 스마트폰이 없던 시절 문자로 단체일정을 잡기 위해서는 아래의 그림과 같이 개개인에게 연락을 했어야 했다. 스마트폰의 등장이후로 단체톡방(Mediator)을 만들어서 메세지(일정)를 보내면 된다 [Mediator] class Meditator { public: virtual ~Meditator() {} void addColleague(Colleague* collegue) { this->collegues.push_back(collegue); } ..
Command Pattern (명령 패턴) 목적 Client가 어떤 기능에 대한 요청을 할 때 요청을 직접 호출하지 않고 요청자체를 캡슐화한다. 명령 패턴의 핵심은 연산을 실행하는 데 필요한 인터페이스를 선언해 놓은 Command 추상 클래스이다. Client입장에서는 필요한 구체화된 Command만 설정해주면 된다. 사용 시나리오 Iot 허브가 있고 허브에서 연결된 things를 제어한다고 가정한다. Iot허브는 Invoker가 되고 things는 Receiver가 된다. things 각각의 명령어를 command로 구체화 한다. 해당 예에서는 IoT기능이 있는 IotTV를 Command패턴을 통해 제어하는 예이다. [Receiver] class IotTV { //Receiver public: void..
Chain of Responsibility Pattern (책임 연쇄 패턴) 목적 Request를 보내는 객체와 받는 객체들 간의 결합도를 없애기 위한 패턴이다. 하나의 Request에 대한 처리가 여러 객체에서 가능하다. 현재 객체에서 처리했거나 혹은 처리하지 못한 request를 다음 객체로 넘김으로써 다른 객체에서 Request를 처리할 수 있는 기회를 준다. 이러한 방식은 링크드 리스트 자료구조와 유사하다. 결론적으로 하나의 Request에대한 여러 처리방식을 유연하게 연결(추가)할 수 있다. 사용 시나리오 어떤 API를 사용하기 위해서 인증절차를 거쳐야 한다. 인증 요청은 id값과 token값으로 한다. 인증과정 절차는 id를 확인하는 과정과 token을 확인하는 과정 총 두가지이다. [Requ..
Proxy Pattern (프록시 패턴) 목적 Proxy(대리자, 대리인) pattern은 A라는 객체를 접근, 제어하기 위해 대리자인 proxyA를 통해서만 접근 가능하도록 하는 구조를 만드는 패턴이다. 또한 이 패턴은 A라는 객체를 실제로 사용하기 전까지는 객체 생성과 초기화에 들어가는 비용을 발생시키지 않겠다는 의미이다.(포인터와 유사) 또한 proxyA객체는 A객체의 속성값을 변경시켜서는 안된다. 사용 시나리오 어떤 웹페이지 하단에 이미지가 존재한다고 가정한다. 해당 이미지는 사용자가 스크롤을 내릴때만(필요할때만) 불러오게 구현한다. [Subject(interface)] class Image { public: virtual void renderImage() = 0; virtual ~Image();..
Flyweight Pattern (플라이웨이트 패턴) 목적 동일한 객체를 관리하고 공유하여 메모리를 절약한다. 객체관리는 팩토리를 통해서 하며 객체들을 중복없이 관리하기 위해 map자료구조를 활용한다. 사용 시나리오 어떤 플렛폼에서 광고용 영상 컨텐츠를 관리한다고 가정한다. 사용자가 컨텐츠를 요구할 때 파일을 한번만 로딩한 뒤 다음 사용자 부터는 로딩하지 않고 컨텐츠를 제공한다. [Flyweight] class Contents { public: virtual void play() = 0; }; [ConcreteFlyweight] class Movie : public Contents { public: Movie(string title) { this->title = title; cout
Facade Pattern (퍼사드 패턴) 목적 복잡한 서브시스템 내의 인터페이스 집합에 대해서 사용자에게 꼭 필요한 획일화된 인터페이스만을 제공한다. Facade는 사전상 의미로 표면, 겉, 외관을 의미한다. 의미 그대로 복잡한 서브시스템은 속으로 숨기고 사용자에게 필요한 인터페이스만 표면(Facade)로 보여준다. 이러한 패턴은 사용자와 서브시스템 간의 결합도를 줄여준다. 사용 시나리오 c, c++파일을 빌드할 수 있는 시스템을 작성한다고 가정한다. 빌드 시스템은 전처리->컴파일->어셈블->링크 의 과정을 거치며 각각의 과정은 복잡한 서브시스템으로 구성되어있다. 그 중 컴파일 서브시스템은 소스코드를 파싱하고 어셈블리 코드를 생성해내는 인터페이스를 제공한다.(실제로는 더 복잡함) 퍼사드 패턴을 통해 컴..
Bridge Pattern (가교 패턴) 목적 추상적 개념에 해당하는 클래스 계통(Abstraction)과 구현에 해당하는 클래스 계통(Implementor)을 분리한다. 상속을 통한 구현은 구현과 추상적 개념을 영구적으로 종속시키기 때문에 수정, 확장이 쉽지 않다. 따라서 가교 패턴을 통해 수정, 확장의 용이점을 갖는다. 사용 시나리오 태블릿 디바이스가 9인치, 11인치, 13인치를 개발한다고 가정한다. 각 태블릿 마다 화면을 디스플레이한다는 공통점은 있지만 세로와 가로길이에 따라 구체적인 디스플레이 방법은 다르며 이를 각각 구현해야 한다. [Implementor] class DisplayImpl { //Implementor public: virtual void showDisplay() = 0; vir..