1. Design Pattern 이란?

디자인패턴이란 각 모듈의 세분화된 역할이나 모듈들 간의 인터페이스와 같은 코드를 작성하는 수준의 세부적인 구현 방안을 설계할 때 참조할 수 있는 전형적인 해결 방식 또는 예제를 말한다.

 

디자인 패턴은 문제 및 배경, 실제 적용된 사례, 재사용이 가능한 샘플 코드 등으로 구성되어 있다.

바퀴를 다시 발명하지 마라 (Don't reinvent the wheel)' 이라는 말과 같이, 개발 과정 중에 문제가 발생하면 새로 해결책을 구상하는 것보다 문제에 해당하는 디자인 패턴을 참고하여 적용하는 것이 더 효율적이다.

디자인 패턴은 한 패턴에 변형을 가하거나 특정 요구사항을 반영하면 유사한 형태의 다른 패턴으로 변화되는 특징이 있다.

디자인 패턴은 1995GoF (Gang of Four)라고 불리는 에릭 감마, 리차드 헬름, 랄프 존슨, 존 블리시디스가 처음으로 구체화 및 체계화 하였다.

GoF의 디자인 패턴은 수많은 디자인 패턴들 중 가장 일반적인 사례에 적용될 수 있는 패턴들을 분류하여 정리함으로써, 지금까지도 소프트웨어 공학이나 현업에서 가장 많이 사용되는 디자인 패턴이다.

GoF의 디자인 패턴은 유형에 따라 생성 패턴 5, 구조 패턴 7, 행위 패턴 11개 총 23개의 패턴으로 구성된다.

 

 

2. 디자인패턴의 등장 배경

개발자들은 개발을 하면서 프로그램의 유연성, 확장성과 관련된 비슷한 문제들을 마주하며 이 문제들을 풀기 위해 많은 시간을 소요한다. 만약 이 문제들에 해결책이 있다면 어떨까? 문제를 풀기 위한 시간을 줄일 수 있을 것이다. 이러한 생각에서 만들어진 것이 디자인 패턴이다.

디자인 패턴은 개발을 하면서 생길 수 있는 문제를 유형별로 나눠서 해결책을 제시한다. , 디자인 패턴은 일종의 수학 공식 같은 역할을 한다. 디자인 패턴을 참고하여 개발할 경우 개발의 효율성과 유지 보수성, 운용성이 높아지며 프로그램의 최적화에 도움이 된다.

 

 

3. 디자인 패턴과 협업

디자인 패턴은 프로그래머들 사이에서 공유되는 패턴이다. 프로그래머들이 의사소통할 때 양쪽 모두 디자인 패턴을 알고 있다면 간단한 단어도 복잡한 의사소통을 대체하는 것이 가능해진다. 의사소통을 간단한 단어로 대체하는 것이 가능해지면, 프로그래밍 구조 관점에서 프로그램에 대해 논의하는 것이 수월해진다. 더욱 높은 레벨에서 의사소통을 함으로써 더욱 쉽게 이해할 수 있게 된다.

 

 

4. 디자인패턴과 프로그래밍

많은 프로그래머들이 디자인 패턴을 중요하게 생각하는 이유는 바로 디자인 패턴을 통해 프로그램 설계에 대한 추상화를 할 수 있기 때문이다. 디자인 패턴은 우리가 프로그램을 객체관점보다 높은 레벨에서 생각할 수 있도록 도와준다. 만약 너무 낮은 레벨에서 프로그램을 다루게 된다면 높은 레벨의 생각이 어려워지는 것과 같은 이치이다.

아래와 같은 휴지통이 있다고 해보자. 휴지통을 휴지라는 단어 없이 다른 사람에게 묘사한다고 해보자. 어떻게 하겠는가.

 

 

 

아마 다음과 같이 설명할 것이다.

 

휴지통 : 안에 얇고 부드러운 사각형 천이 여러 개 들어 있는 통

 

만약 휴지통이라는 고차원적(고레벨)인 단어를 안다면 이를 그냥 휴지통이라고 하면 되지만, 휴지통이라는 단어를 쓸 수 없다면 다음과 같이 장황하게 설명(낮은 레벨)을 해야 한다. 따라서 낮은 레벨로 설명하는 것은 장황하고 이해하기 어려워진다.

프로그램도 찬가지이다. 프로그래밍 전문가들은 디자인 패턴을 장황하게 설명하지 않고 디자인 패턴 그 자체의 이름만을 말해서 프로그램설계의 복잡성을 줄인다.

 

 

5. 디자인 패턴 사용의 장단점

장점 범용적인 코딩 스타일로 인해 구조 파악이 용이하다
객체지향 설계 및 구현의 생산성을 높이는 데 적합하다
검증된 구조의 재사용을 통해 개발 시간과 비용이 절약 된다
개발자간의 원활한 의사소통이 가능하다
설계 변경 요청에 대한 유연한 대처가 가능하다
단점 초기 투자비용이 부담될 수 있다
객체지향을 기반으로 한 설계와 구현을 다루므로 다른 기반의 애플리케이션 개발에는 적합하지 않다

 

 

 

6. 디자인 패턴 유형

1) 생성패턴 (Creational Pattern)

Abstract Factory - 구체적인 클래스에 의존하지 않고 서로 연관, 의존하는 객체
들의 그룹으로 생성하여 추상적으로 표현 한다
- 연관된 서브 클래스를 묶어 한 번에 교체하는 것이 가능하다
Builder - 작게 분리된 인스턴스를 건축하듯이 조립하여 객체를 생성 한다
- 객체의 생성 과정과 표현 방법을 분리하고 있어, 동인한 객체
생성에서도 서로 다른 결과를 만들어 낼 수 있다
Factory Method - 객체 생성을 서브 클래스에서 처리하도록 분리하여 캡슐화한
패턴이다
- 상위 클래스에서 인터페이스만 정의하고 실제 생성은 서브
클래스가 담당한다
- 가상 생성자(Virtual Constructor) 패턴이라고도 한다
Prototype - 원본 객체를 복제하는 방법으로 개게를 생성하는 패턴
- 일반적인 방법으로 객체를 생성하며, 비용이 큰 경우 주로
이용한다
Singleton - 하나의 객체를 생성하면 생성된 객체를 어디서든 참조할 수
있지만, 야러 프로세스가 동시에 참조할 수는 없다
- 클래스 내에서 인스턴스가 하나뿐임을 보장하며 불필요한
메모리 낭비를 최소화할 수 있다

생성패턴은 객체의 생성과 관련된 패턴으로 총 5개의 패턴이 있다. 객체의 생성과 참조 과정을 캡슐화 하여 객체가 생성되거나 변경되어도 프로그램의 구조에 영향을 크게 받지 않도록 하여 프로그램에 유연성을 더해준다.

 

추상 팩토리 (Abstract Factory)

추상적인 공장이라는 의미는 언뜻 생각하면 너무 뜬금없는 단어의 조합이다. 하지만 조금 더 생각해보면 추상적인 공장에서는 추상적인 제품을 만들 것이라는 말이 될 것이고, 그 말은 다시 말해 추상적인 공장은 추상적인 부품을 이용해 추상적인 제품을 만든다.

말로 하면 이해하기 힘들지만, 객체지향에 있어 추상(abstract)이란 단어를 생각할 필요가 있다. 객체지향의 추상을 생각하면서 설명하자면, ‘구현부에 신경 쓰지 않고 인터페이스(API)만 생각하는 상태라는 의미다.

정리하자면, 부품의 구현부에 신경 쓰지 않고 인터페이스(API)에 집중하여, 인터페이스만을 사용해 부품을 조립하고 제품으로 완성하는 방법이다.

 

빌더 (Builder)

도시에 빌딩을 짓는 것을 build라 한다. 빌딩을 짓는 순서는 우선 지반을 다지고 골격을 세우고, 아래에서 위로 조금씩 만들어 간다. 이처럼 복잡한 구조물을 한 번에 완성시키는 것은 어렵기 때문에 전체를 구성하는 각 부분을 만들면서 단계를 밟아가며 만든다. Builder 패턴 또한 이처럼 구조를 가진 인스턴스를 쌓아 올리는 방식의 패턴이다.

 

팩토리 메소드 (Factory Method)

객체를 만들어내는 부분을 서브 클래스 (SUB-CLASS)에 위임하는 패턴이다. new 키워드를 호출해 객체를 생성하는 역할을 서브 클래스에 위임하는 것이다. 결국 팩토리 메소드 패턴은 객체를 만들어내는 공장을 만드는 패턴이라 할 수 있다.

팩토리 메소드 패턴에서는 인스턴스를 만드는 방법을 상위 클래스 측에서 결정하지만 구체적인 클래스명 까지는 결정하지 않는다.

구체적인 내용은 모두 하위 클래스 측에서 수행한다. 따라서 인스턴스 생성을 위한 골격(framework)과 실제의 인스턴스 생성의 클래스를 분리해서 생각할 수 있다.

 

포로토타입 (Prototype)

특정 캑체의 인스턴스를 생성할 때 우리는 new 명령어를 사용해서 생성한다. 이처럼 new를 사용해 인스턴스를 만들 경우에는 클래스 이름을 반드시 지정해야 한다. 하자만 클래스명을 지정하지 않고 인스턴스를 생성할 때도 있다.

인스턴스로부터 다른 인스턴스를 만드는 것을 복사기를 사용하는 것과 비슷하다. 언본 서류를 어떻게 만들었는지 몰라도 복사기로 같은 종류의 서류를 몇 장이든 만들 수 있다. Java에서는 cloneable 인터페이스와 clone 메소드를 이용한다.

 

싱글톤 (Singleton)

우리는 보통 new 명령어를 통해 인스턴스를 생성해서 사용한다. new를 통해 IDCard 클래스를 10번 호출하면 10개의 IDCard 인스턴스가 생기는 것이다. 그런데 클래스의 인스턴스가 단 하나만 필요한 경우가 있다. 시스템안에서 하나의 인스턴스만 생성 되서 사용되어야 하는 클래스들인데, 예를 들면 회사내의 공공재로 사용하는 프린터나 컴퓨터 등이 그렇다. 우리가 원한다고 마음대로 new를 통해 생성할 수 없다.

물론 조심해서 new를 한 번만 사용해서 1개의 인스턴스만 사용하겠다고 할 수도 있지만, 이것은 결코 지정한 클래스가 절대로’ 1개 밖에 존재하지 않는 것을 보증할 수 없었다. 이처럼 인스턴스가 한 개밖에 존재하지 않는 것을 보증하는 패턴을 Singleton Pattern 이라 한다.

 

 

2) 구조 패턴 (Structural Pattern)

구조패턴은 클래스나 객테들을 조합하여 더 큼 구조로 만들 수 있게 해주는 패턴으로 총 7개의 패턴이 있다. 구조 패턴은 구조가 복잡한 시스템을 개발하기 쉽게 도와준다.

Adapter - 호환성이 없는 클래스들의 인터페이스를 다른 클래스가 이
용할 수 있도록 변환해주는 패턴이다
- 기존의 클래스를 이용하고 싶지만 인터페이스가 일치하지
않을 때 이용한다
Bridge - 구현부에서 추상층을 분리하여, 서로가 독립적으로 확장할
수 있도록 구성한 패턴이다
- 기능과 구현을 두 개의 별도 클래스로 구현한다
Composite - 여러 객체를 가진 복합 객체와 단일 객체를 구분 없이 다루
고자 할 때 사용하는 패턴이다
- 객체들을 트리 구조로 구성하여 디렉터리 안에 디렉터리가
있듯이 복합 객체 안에 복합 객체가 포함되는 구조를 구현
할 수 있다
Decorator - 객체 간의 결합을 통해 능동적으로 기능들을 확장할 수 있
는 패턴이다
- 임의의 객체에 부가적인 기능을 추가하기 위해 다른 객체들
을 덧붙이는 방식으로 구현한다
Facade - 복잡한 서브 클래스들을 피해 더 상위에 인터페이스를 구성
함으로써 서브 클래스들의 기능을 간편하게 사용할 수 있
도록 하는 패턴이다
- 서브 클래스들 사이의 통합 인터페이스를 제공하는
Wrapper객체가 필요하다
Flyweight - 인스턴스가 필요할 때마다 매번 생성하는 것이 아니고 가능
한 한 공유해서 사용함으로써 메모리를 절약하는 패턴이다
- 다수의 유사 객체를 생성하거나 조작할 때 유용하게 사용할
수 있다
Proxy - 접근이 어려운 객체와 여기에 연결하려는 객체 사이에서 인
터페이스 역할을 수행하는 패턴이다
- 네트워크 연결, 메모리의 대용량 객체로의 접근 드에 주로
이용한다

 

어댑터 패턴 (Adapter Pattern)

외국의 전자 제품 중에는 전원 어댑터 규격이 한국과는 달라서 사용하기 곤란한 경우가 있다. 이럴 때 변환 어댑터를 이용해 한국 콘센트에서도 사용할 수 있도록 한다. , 클라이언트의 도구 타입과 반환 타입이 다르더라도 중간에 어댑터를 둠으로써 적절히 가공하여 둘을 연결지어준다는 것이다.

어댑터 패턴을 사용하면 전혀 다른 인자값을 가지도고 몇몇 알고리즘을 사용해서 로직을 수행할 수 있다.

 

브릿지 패턴 (Bridge Pattern)

'기능의 클래스 계층구현의 클래스 계층간에 다리를 놓는 역할을 하는 패턴이다.

 

Composite Pattern

전체와 부분을 동일시해서 재귀적인 구조를 만들기 위한 디자인 패턴이다.

맥에서는 파인더, 윈도우에서는 폴더, 컴퓨터 파일 시스템에서는 디렉토리라는 것이 있다. 이 디렉토리는 개발 당시 프로젝트의 package와 동일하게 그 안에 또 다른 디렉토리가 있을 수도 있고 파일이 있을 수도 있다. 이처럼 디렉토리 내부에 또 디렉토리가 있는 구조인 재귀적인 구조를 만들어 낸다.

디렉토리와 파일의 공통점은 둘 다 디렉토리 안에 넣을 수 있다는 것이고 이 둘을 합쳐 디렉토리 엔트리라고 부르기도 한다.

예를 들어 하나의 디렉토리를 가지고 내부에 무엇이 있는지 차례대로 조사할 경우 조사대상은 디렉토리일수도 있고, 파일일수도 있다. 다시 말하자면, ‘디렉토리 엔트리를 차례대로 조사하는 것이다.

이렇게 두 종류를 하나의 디렉토리 엔트리로 같은 종류로 취급할 경우 디렉토리 안에는 다른 디렉토리를 넣을 수도 있고 파일을 넣을 수도 있다. 이 행위는 그 다음에도 동일하다. , 재귀적인 구조를 만들 수 있다.

 

Decorator

원천 객체(Object)에 기능을 추가해나가는 디자인 패턴. 개발을 하다보면 가끔 전체 클래스에 새로운 기능을 추가할 필요는 없지만, 특정 객체에는 새로운 기능이 추가되어야 하는 경우가 있다. 예를 들어 Box라는 객체에는 좌우측 측면에 손잡이 목적의 구멍이 없지만 어떤 Box에는 필요할 수도 있다. 이런 경우 해당 박스에 새로운 속성이 추가되야 한다.

일반적으로 위와 같은 기능 및 속성추가를 하는 방법은 상속을 이용한다. Box를 상속받는 BoxWithHole 이라는 SubClass를 만드는 방법이다. 하지만 해당 방법은 적절한 방법이 아니다. 손잡이구멍의 선택은 정적이기 때문이다. 사용자는 구성요소를 언제 어디서 어떻게 손잡이를 구성할지 제어할 수 없기 때문이다.

그래서 기존의 Box라는 객체를 감싸서 다른 기능(손잡이)을 추가해주는 객체를 Decorator라고 한다. Decorator는 자신이 둘러싼 속성과 기능도 동일하게 제공하기 때문에 Decorator의 존재는 이를 사용하는 사용자에게 감춰진다. 그리고 사용자가 기존 객체에 대한 요청을 중간에 가로채서 해당 객체에 전달하는데, 그 사이에 전-후 처리로 다른 작업을 추가할 수 있고, 이 경우 투명성이 존재하기에 Decorator의 중첩이 가능하고 이를 통해 기능 추가를 계속할 수 있게 된다.

 

Facade

facade는 프랑스어의 façade를 어원으로 하는 건물의 정면이라는 의미인데, , 프로그램의 정면에서 요구를 받아서 전해주는 역할이라 할 수 있다. Facade Pattern은 복잡하게 얽혀 있는 것을 정리해서 높은 레벨의 인터페이스(API)를 제공한다. Facade 역할은 시스템 외부에는 단순한 인터페이스(API)를 보여주고 시스템 내부에 있는 까 클래스의 역할이나 의존관계를 생각해 정확한 순서로 클래스를 이용한다.

 

Flyweight

인스턴스를 공유시키면서 불필요한 인스턴스를 생성하지 않게 하는 패턴이다.

권투에서 Flyweight 급은 가장 체중이 가벼운 체급을 말한다. 디자인 패턴에서 Flyweight 역시 각각의 객체를 가볍게하는 기법인데, 객체는 실물이 존재하지 않기 때문에 따로 무게가 있는 것은 아니고 메모리의 사용량을 가볍게 한다는 의미로 쓰인다.

자바에서는 new 키워드를 통해 인스턴스를 생성하는데, 이 인스턴스는 각각 메모리를 차지하게 되고, 이 인스턴스가 많을수록 메모리의 사용량을 올라간다는 말인즉슨, 무거워진다는 말이 된다. 그렇기에 인스턴스를 최대한 필요한 곳끼리 공유를 시켜서 인스턴스의 생성을 막아 메모리의 사용량을 가볍게 하는 기법이다.

 

 

Proxy

필요해지면 만드는 패턴이다. 'Proxy'의 의미는 대리인이다. 대리인은 말 그대로 누군가를 대신한다는 의미이며, 본인이 아니라도 가능한 일을 대리인이 할 수 있다. 하지만 대리인의 역량을 벗어나는 일이 발생하면 본인이 와서 일 처리를 해야 한다. 객체지향에서는 본인대리인도 객체가 된다. JPALayloading과도 관련이 있는데, 매번 실제 DB를 조회해서 엔티티를 만들어 반환하는 것이 아닌 따로 쓸 일이 없는데 다른 엔티티에 묶어서 같이 조화되었지만, 따로 참조될 일은 없는 경우 틀만 같은 Proxy 객체만 있어도 된다. 그리고 이렇게 Proxy객체로 처리를 하게 되면 불필요한 DB조회를 막아 성능도 올라갈 수 있다.

 

 

3) 행위 패턴 (Behavioral Pattern)

행위패턴은 클래스나 객체들이 서로 상호작용하는 방법이나 책임 분배 방법을 정의하는 패턴으로 총 11개의 패턴이 있다. 하나의 객체로 수행할 수 없는 작업을 여러 객체로 분배하면서 결합도를 최소화 할 수 있도록 도와준다.

Chain of Responsibility - 요청을 처리할 수 있는 객체가 둘 이상 존재하여 한 객체가
처리하지 못하면 다음 객체로 넘어가는 형태의 패턴이다
- 요청을 처리할 수 있는 각 객체들이 고리(Chain)으로 묶여 있
어 요청이 해결될 때까지 고리를 따라 책임이 넘어간다
Command - 요청을 객체의 형태로 캡슐화 하여 재이용하거나 취소할 수
있도록 요청에 필요한 정보를 저장하거나 로그에 남기는 패턴
이다
- 요청에 사용되는 각종 명령어들을 추상 클래스와 구체 클래스
로 분리하여 단순화한다
Interpreter - 언어에 문법 표현을 정의하는 패턴이다
- SQL 이나 통신 프로토콜과 같은 것을 개발할 때 사용한다
Iterator - 자료 구조와 같이 접근이 잦은 객체에 대해 동일한 인터페이
스를 사용하도록 하는 패턴이다
- 내부 표현 방법의 노출 없이 순차적인 접근이 가능하다
Mediator - 수많은 객체들 간의 복잡한 상호작용(interface)을 캡슐화하여
객체로 정의하는 패턴이다
- 객체 사이의 의존성을 줄여 결합도를 감소시킬 수 있다
Memento - 특정 시점에서의 객체 내부 상태를 객체화함으로써 이후 요청
에 따라 객체를 해당 시점의 상태로 돌릴 수 있는 기능을 제
공하는 패턴이다
- Ctrl+Z 와 같은 되돌리기 기능을 개발할 때 주로 이용한다
Observer - 한 객체의 상태가 변화하면 객체에 상속되어 있는 다른 객체
들에게 변화된 상태를 전달하는 패턴이다
- 주로 분산된 시스템 간에 이벤트를 생성발생(Publish)하고,
를 수신(Subscribe)해야 할 때 이용한다
State - 객체의 상태에 따라 동ㅇ일한 동작을 다르게 처리해야 할 때
사용하는 패턴이다
- 객체 상태를 캡슐화하고 이를 참조하는 방식으로 처리한다
Strategy - 동일한 계열의 알고리즘들을 개별적으로 캡슐화하여 상호 교
환할 수 있게 정의하는 패턴이다
- 클라이언트는 독립적으로 원하는 알고리즘을 선택하여 사용할
수 있으며, 클라이언트에 영향 없이 알고리즘의 변경이 가능하다
Template Method - 상위 클래스에서 골격을 정의하고, 하위 클래스에서 세부 처
리를 구체화하는 구조의 패턴이다
- 유사한 서브 클래스를 묶어 공통된 내용을 상위 클래스에서
정의함으로써 코드의 양을 줄이고 유지보수를 용이하게 해준
Visitor - 각 클래스들의 데이터 구조에서 처리 기능을 분리하여 별도의
클래스로 구성하는 패턴이다
- 분리된 처리 기능은 각 클래스를 방문(visit)하여 수행한다

 

Chain of Responsibility

여러 객체를 연결해서 연결된 객체를 순회하며 요청을 처리할 객체를 결정하는 방법이다. 책임이라고 할 수도 있고, 요청이라고 할 수 있는데, 사용자의 요청을 처리할 객체를 직접 결정할 수 없는 경우, 복수의 객체를 사슬(chain)처럼 연결해두면, 그 객체의 사슬을 차례로 돌아다니면서 목적한 객체를 결정하는 방법이다.

해당 패턴을 사용하면 요청하는 쪽처리하는 쪽의 연결을 유연하게 해서 각 객체를 부품으로 독립시킬 수 있다. 또한 상황에 따라서 요청을 처리할 객체가 변하는 프로그램에서도 대응할 수 있다.

학교의 수업시간을 예를들면, 수학시간에 수학선생님이 문제풀이를 7번 학생에게 시켰는데, 7번 학생이 풀지 못하면 그 다음 8, 9, 10번 순으로 (혹은 선생님이 정한 규칙) 다른 하생들에게 문제를 풀어야 할 책임이 주어지고 해당 문제풀이를 처리할 수 있는 학생이 나타나면 문제는 해결된다. 이것을 책임 사슬 패턴이라 한다

 

Command

요청 자체를 객체로 캡슐화하여 인자값으로 여러 명령(command)들을 수행시킬 수 있다.

 

Interpreter

미니언어라는 문법을 클래스화 한 구조로써 미니언어로 정의되어있는 일련의 언어를 분석 및 파싱하는 패턴이다. 미니 프로그램은 그 자체로는 동작하지 않고 Java 언어로 통역(interpreter)역할을 하는 프로그램을 만들어서 분석해준다. 문법 규칙이 많아질수록 복잡해지고 무거워지기 때문에 너무 많아진다 시을 때는 컴파일러 생성기를 쓰거나 파서를 쓰는게 좋다.

 

Iterator

컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항복에 접근할 수 있게 해주는 방법을 제공해주는 패턴이다. iterator 패턴을 사용하면 집합체 내에서 어떤 식으로 일이 처리되는지 몰라도 그 안에 들어있는 항목들에 대해서 반복작업을 수행할 수 있다.

 

Mediator

사공이 많으면 배가 산으로 간다라는 말이 있다. 하나의 배에 사공이 10명이 있다고 하면 사공이 각자 자기주장을 하고 지시를 하며 혼란한 상황이 발생한다. 말 그대로 목적지로 가지 못하고 이상한 산에 도착할 수 있다. 이럴 때 중간에서 사공들의 의견과 요청을 종합하여 지시를 내려줄 중개인이 필요하다. 중개인이 있으면 사공은 모두 중개인에게 보고를 하고, 중개인이 사공들에게 지시를 내릴 수 있게 되면 혼란이 사라지게 될 수 있다. 중재자 패턴에서는 중개인을 mediator(조정자), 각 사공을 colleague(동료)라고 한다.

 

Memento

우리가 자주 사용하는 단축키 중엔 Ctrl+Z가 있다. 텍스트 에디터의 undo(실행취소or되돌리기) 기능이다. 객체지향 프로그램에서 undo기능을 사용하기 위해선 인스턴스가 가지고 있는 정보를 저장해 둘 필요가 있다. 다만, 저장만 할게 아니라 저장한 정보로부터 인스턴스를 원래의 상태로 되돌려야 한다.

여기서 고려해야 할 부분이 있는데, 인스턴스를 복원하기위해서는 인스턴스 내부의 정보를 자유롭게 접근할 수 있어야 하는데, 접속이 제한되야 하는 부분마저 접근이 허용되면 클래스 내부 구조에 의존한 코드가 프로그램의 여기저기로 흩어져 수정이 어려워진다. 이것을 캡슐화의 파괴라 한다. Memento Pattern은 캡슐화의 파괴에 빠지지 않고 저장과 복원을 실행한다.

 

Observer

객체 사이에 일 대 다의 의존 관계를 정의해 두어, 어떤 객체의 상태가 변할 때 그 객체에 의존성을 가진 다른 객체들이 그 변화를 통지받고 자동으로 갱신될 수 있게 만든다.

 

State

객체(object)를 표현함에 있어 구체적인 사물이 현실에 존재하는 경우도 있고 아닌 경우도 있다. 경우에 따라서는 이런게 클래스가 될 수 있는가 싶은 것들도 클래스로 할 때가 있는데. State 패턴에서는 상태를 클래스로 표현한다.

 

Strategy

여러 알고리즘을 하나의 추상적인 접근점(Interface)을 만들어 접근점에서 서로 교환기능(Deligate)하도록 하는 패턴이다.

 

Template Method

template는 비유하자면 일종의 붕어빵 틀, 타코야키 틀과 비슷하다고 볼 수 있으며, 알고리즘의 구조를 method에 정의하고 하위 클래스에서 알고리즘 구조의 변경 없이 알고리즘을 재정의 하는 패턴이다.

 

Visitor

데이터 구조 안에는 많은 요소가 저장되어 있고, 그 각 요소에 대해서 처리해 간다고 할 때 처리부분은 어디에 정의되어야 할까. 평범하게 생각하면 데이터 구졸르 표시하고 있는 클래스 내에 정의를 할 것입니다. 하지만 그 처리가 여러 종류라면 새로운 처리가 필요할 때마다 데이터 구조의 클래스를 수정해야 한다.

visitor pattern에서는 데이터 구조와 처리를 분리하여 데이터 구조 내부를 순회하는 방문자(visitor)클래스를 준비해서 그 클래스에게 처리를 위임한다. 이렇게 설계를 할 경우 새로운 처리를 추가할 때는 새로운 ‘visitor'을 만들면 된다. 그리고 데이터 구조 영역에서는 순회하려는 방문자에 대해 접근을 허용하면 된다.

 

 

 

 

 

 

 

참고문헌>>

 

https://sourcemaking.com/design_patterns

 

https://m.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS8616098823&cate_cd=

 

김문권라현정김수동, 2012, 서비스 지향 컴퓨팅을 위한 GoF 디자인 패턴 적용기법

 

 

 

 

 

+ Recent posts