Design Pattern Flashcards Preview

PE > Design Pattern > Flashcards

Flashcards in Design Pattern Deck (24):
1

디자인 패턴

▣ 정의
- 반복적으로 일어나는 문제들을 설명하고, 그 문제들에 대한 해법의 핵심을 설명하는 경험적 패턴
▣ 요소 (이문해결)
- 이름 : 문제와 해법을 서술
- 문제 : 문제와 배경
- 해법 : 관계, 책임 설명
- 결과 : 결과와 장단점
▣ 원칙
- 바뀌는 부분은 캡슐화
- 상속보다는 위임
- 구현이 아닌 인터페이스에 맞게
- 가능하면 느슨하게 결합
- SOLID
▣ 분류
- 객체생성 패턴
- 구조개선 패턴
- 행위개선 패턴
▣ 23개의 디자인 패턴(팩앱빌프싱 앱브컴데파플프 인템체커이메메옵스스비)
1) 생성
- Factory Method : 인스턴스화될 객체의 서브클래스
- Abstract Factory : 제품객체군
- Builder : 복합 객체 생성
- Prototype : 인스턴스화될 객체 클래스
- Singleton : 인스턴스가 하나일 때
2) 구조
- Adaptor : 상속
- Adaptor : 위임
- Bridge : 객체 구현
- Composite : 객체의 합성과 구조
- Decorator : 서브클래싱 없이 객체의 책임성
- Facade : 서브시스템에 대한 인터페이스
- Flyweight : 객체 저장 비용
- Proxy : 객체 접근방법
3) 행위
- Interpreter : 언어의 문법과 해석방법
- Template Method : 알고리즘 단계
- Chain of Responsibility : 요청처리 객체
- Command : 요청 처리 시점과 방법
- Iterator : 집합객체 요소 접근/순회방법
- Mediator : 객체 상호 작용
- Memento : 객체 상호 작용
- Observer : 종속객체 상태 변경
- State : 객체 상태
- Strategy : 알고리즘
- Visitor : 클래스변경없이 객체에 적용할 수 있는 오퍼레이션

2

Abstract Factory

▣ 정의
- 클라이언트에서 구상 클래스를 지정하지 않으면서도 일군의 객체를 생성할 수 있도록 하는 패턴
▣ 활용
- 시스템을 독립적으로 만들고자 할 때
- 한번 구성한 제품을 다른 것으로 대체 가능 할 때
- 제품이 갖는 제약사항을 따라야 할 때
▣ 결과
- 추상 인터페이스를 통해서만 클라이언트 프로그램 작성
- 쉬운 제품군 대체
- 제품간의 일관성 증진
▣ 참여객체
- AbstractFactory : 개념적 공장
- ConcreteFactory : 구체적 공장
- AbstractProduct : 개념적 제품
- ConcreteProduct : 구체적 제품
- Client

3

Factory Method

▣ 정의
- 생성할 구상 클래스를 서브 클래스에서 결정
▣ 활용
- 생성할 객체 타입을 예측할 수 없을 때
- 객체 생성의 책임을 서브클래스에 위임시키고 서브클래스에 대한 정보를 은닉하고자 할 때
▣ 결과
- 애플리케이션에 국한된 클래스가 코드에 종속될 필요를 제거
- 서브클래스에 대한 Hook 메소드 제공 (객체별 다른 기능 제공)
▣ 참여객체
- Product(I/F) : 객체의 인터페이스 정의
- ConcreteProduct : Product 인터페이스 구현
- Creator(A) : 팩토리 메소드 선언 (Product 타입 객체 변환)
- ConcreteCreator : 팩토리 메소드 재정의

4

Builder

▣ 정의
- 제품을 여러 단계로 나눠서 만들 수 있도록 제품 생산 단계를 캡슐화
▣ 활용
- 합성할 객체들의 표현이 서로 다르더라도 구축 공정이 이를 지원해야 할 때
▣ 결과
- 제품에 대한 내부 표현을 다양하게 변화
- 생성과 표현에 필요한 코드 분리
- 복합 객체 생성 공정 세밀화
▣ 참여객체
- Builder(I/F) : I/F API 결정, 인스턴스의 각 부분을 만들기 위한 메소드 준비
- ConcreteBuilder(C)(Dependency Product) : I/F API 구현, 인스턴스의 각 부분을 만드는 부분, 조립하는 부분, 최종적으로 인스턴스를 생성하는 부분을 모두 구현
- Director(C)(Aggregation Builder) : I/F API 사용, 원하는 부품 조립 후 인스턴스 생성
Product : Builder에 의해 최종적으로 생산된 제품

5

Prototype

▣ 정의
- 클래스로 부터 인스턴스를 만드는 것이 아니라 인스턴스를 복사해서 새로운 인스턴스 생성 (Clone())
▣ 활용
- 어떤 클래스의 인스턴스를 만드는 것이 자원/시간을 많이 소모하거나, 복잡한 경우 사용
- 종류가 너무 많아 한 개의 클래스로 할 수 없는 경우
▣ 결과
- 클라이언트에서는 새로운 인스턴스를 만드는 복잡한 과정을 몰라도 된다.
- 상황에 따라 객체를 생성하는 것보다 복사하는 것이 더 효율적
- 런타임에 새로운 제품을 삽입하고 삭제 가능
- 객체에 정의된 변수 값에 따라 행위 변경
- 서브 클래스의 수 감소
▣ 참여객체
- Prototype(I/F) : 자신을 복제하는데 필요한 인터페이스를 정의
- ConcretePrototype : 자신을 복제하는 오퍼레이션을 구현
- Client : Prototype에 복제를 요청하여 새로운 객체를 생성

6

Singleton

▣ 정의
- 지정한 클래스의 인스턴스가 반드시 1개만 존재하도록 하는 패턴
▣ 활용
- 유일하게 존재하는 인스턴스가 상속에 의해 확장되어야 할 때
- 클라이언트가 코드 수정없이 확장된 서브클래스의 인스턴스를 사용할 수 있어야 할 때
▣ 결과
- 변수영역 감소 (전역변수를 정의해 발생하는 디버깅의 어려움 제거)
- 인스턴스 개수 변경 용이 (인스턴스 접근 허용 범위 제어)
▣ 참여객체
- static uniqueInstance
- singletonDate
+ static Instance()
+ Operation()
▣ 만드는 방법 (이스래 쓰인 이더)
- Eager Initialization : getInstance()
- Static Block Initialization : static 초기화블럭이용, 클래스 로딩시 최초 한번만 실행, 로직 추가 가능, 에러처리 가능
- Lazy Initialization : getInstance() 에서 null 인 경우만 생성, Multi Thread 방식의 경우 불안전
- Thread safe Initialization : synchronized 사용, 여러 thread 들이 동시에 접근해서 인스턴스를 생성시키는 위험 제거, 수 많은 thread들이 getInstance() 호출로 성능저하 발생
- Initialization on demand holder idiom : jvm의 class loader의 매커니즘과 class의 load 시점을 이용하여 내부에 class를 생성시킴으로써 thread 간의 동기화 문제 해결
- enum Initialization : Instance가 생성될 때, multi thread 로 부터 안전, 단 한번의 인스턴스 생성 보장
- Double Checking Locking : volatile static, synchronized (singleton.class), 인스턴스의 생성여부를 확인 후, 미생성시에만 동기화 수행

7

Adaptor

▣ 정의
- 이미 제공하는 것과 필요한 것 사이의 간격을 매우는 패턴
- 클래스에 의한 Adaptor (상속)
- 인스턴스에 의한 Adaptor (위임)
▣ 활용
- 기존 클래스를 사용해야 하나 인터페이스가 수정되어야 하는 경우
- 이미 만들어진 것을 재사용해야 하나, 재사용 가능한 라이브러리를 수정할 수 없는 경우
▣ 결과
- 클래스 Adaptor : Adaptee에 정의된 행위 재정의 가능
- 객체 Adaptor : Adaptee에 정의된 행위 재정의 어려움
▣ 참여객체
- Client : 어떠한 행위가 필요한 객체 (직류 12볼트 노트북)
- Target(상속) : Client에 필요한 메소드 제공 (직류 12볼트)
- Adaptee(위임) : 기존 메소드 가지고 있음 (교류 120볼트)
- Adapter : Adaptee의 메소드 활용, Target이 필요로 하는 메소드 만듦 (교류 120볼트를 직류 12볼트로 바꿔주는 어댑터

8

Bridge

▣ 정의
- 기능의 클래스 계층과 구현의 클래스 계층을 분리하는 패턴
▣ 활용
- 추상화 개념과 이에 대한 구현간의 종속성을 없애고 싶거나, 또는 런타임시 구현 방법을 선택하거나 구현 내용을 변경하고 싶은 경우
▣ 결과
- 인터페이스와 구현의 결합도 약화
- 확장성 제고 (abstraction 과 implementor를 독립적으로 확장)
▣ 참여객체
- Abstraction(A)(Aggregation Implementator) : 기능 클래스 계층의 취상위 클래스 (Display)
- RefineAbstraction(C) : Abstraction의 기능을 확장 (CountDisplay)
- Implementor(I/F) : 구현 클래스 계층의 최상위 클래스 (DisplayImpl)
- ConcreteImplementor(C) : Implementor 클래스 구체적 구현 (WinImpl, MacImpl)

9

Composite

▣ 정의
- 객체들의 관계를 트리구조로 구성하여 부분-집합 계층을 표현하는 패턴
▣ 활용
- 부분-집합 관계의 계층도를 표현해야 할 때
▣ 결과
- 하나의 일관된 계층도 정의
- 새로운 요소를 쉽게 추가
- 범용성 있게 설계
▣ 참여객체
- Component(I/F) : 집합 관계에 정의될 모든 객체에 대한 인터페이스 정의(공통의 행위 구현)
- Leaf(C) : 집합 관계에 포함되기만 하는 가장 기본이 되는 행위 정의
- Composite(C)(Children) : 복합 객체에 대한 행위를 정의
- Client : Component 인터페이스를 통해 집합 관계에 있는 객체들을 관리

10

Decorator

▣ 정의
- 객체에 추가 요소를 동적으로 장식 해가는 패턴
▣ 활용
- 동적으로 객체에 새로운 서비스를 추가할 때
▣ 결과
- 클라이언트에게 일관된 인터페이스를 제공하는 껍데기
▣ 참여객체 (Composite 에서 Decorator Class 추가)
- Component(I/F) : 동적으로 추가할 서비스를 가질 가능성이 있는 객체들에 대한 인터페이스
- ConcreteComponent(C) : 추가적인 서비스가 실제로 정의되어야 할 필요가 있는 객체
- Decorator(C)(Composite) : Component 객체에 대한 참조자를 관리하면서 Component에 정의된 인터페이스를 만족하도록 인터페이스를 정의
- ConcreteDecorator(C) : Component에 새롭게 추가할 서비스를 실제로 구현하는 클래스

11

Facade

▣ 정의
- 서브시스템의 복잡한 인터페이스를 단순화된 하나의 인터페이스로 제공
▣ 활용
- 복잡한 서브시스템에 대한 단순한 인터페이스 제공이 필요할 때
▣ 결과
- 서브시스템의 구성 요소 보호
- 서브시스템과 클라이언트 코드 간의 결합도를 낮춤
- 서브시스템 클래스를 사용하는 것을 완전히 막지는 않음. Facade 또는 서브시스템 클래스를 직접 사용할지 결정
▣ 참여객체
- Facade : 서브시스템의 응용 프로그램 코드와 상호 동작
- Client : 패키지 내의 리소스들을 접근하기 위해 퍼사드 클래스를 사용하는 객체
- Package : 소프트웨어 라이브러리 / API 집합

12

Flyweight

▣ 정의
- 인스턴스를 가능한 한 공유시켜 쓸데없이 new를 하지 않도록 하는 패턴
▣ 활용
- 애플리케이션이 대량의 객체를 사용해야 할 때
- 객체 수가 너무 많아져 저장 비용이 너무 높아질 때
- 대부분의 객체 상태를 부가적인 것으로 만들 수 있을 때
- 애플리케이션이 객체 식별자에 비중을 두지 않는 경우 (식별자를 둔다는 것은 서로 다른 객체로 구별해야 한다는 것이고 이때는 flyweight 객체를 사용할 수 없음)
▣ 결과
- 공유해야 하는 인스턴스의 전체 수를 줄일 수 있다
- 객체별 본질적 상태와 양을 줄일 수 있다
- 부가적인 상태는 연산되거나 저장될 수 있다
▣ 참여객체
- Flyweight(A) : Flyweight 가 받아들일 수 있고, 부가적 상태에서 동작해야 하는 인터페이스를 선언
- ConcreteFlyweight(C) : Flyweight 인터페이스를 구현하고 내부적으로 갖고 있어야 하는 본질적 상태에 대한 저장소를 정의하고 있다. ConcreteFlyweight 객체는 공유할 수 있는 것이어야 한다. 그러므로 관리하는 어떤 상태라도 본질적인 것이어야 한다.
- UnsharedConcreteFlyweight(C) : 모든 Flyweight 서브클래스들이 공유될 필요는 없다. Flyweight 인터페이스는 공유를 가능하게 하지만 그것을 강요해서는 안 된다.
- FlyweightFactory(A)(Aggregation Flyweight) : Flyweight 객체를 생성하고 관리한다. Flyweight가 적절히 공유되도록 보장해야 한다. 클라이언트가 Flyweight를 요청하면 FlyweightFactory 객체는 이미 존재하는 인스턴스를 제공하거나, 만약 존재하지 않는다면 생성해야 한다.
Client : Flyweight에 대한 참조자를 관리하고 Flyweight의 부가적 상태를 저장한다.

13

Proxy

▣ 정의
- 바빠서 그 일을 할 수 없는 본 객체 대신, 대리인 객체가 어느 정도 일을 처리해 주는 패턴
- 객체를 감싸서 그 객체에 대한 접근을 제어
▣ 활용
- 다른 객체에 접근하기 위해 본인 객체는 은닉하고 대리인 객체를 둠 (객체에 대한 참조자 관리가 필요할때)
▣ 결과 (원가보스)
- 원격 프락시 : 원격에 있음에도 불구하고 바로 옆에 있는 것처럼 호출
- 가상 프락시 : 인스턴스가 필요한 시점에만 생성
- 보호용 프락시 : RealSubject 기능에 대해 엑세스 제한을 설정
스마트 프락시 : 객체에 대한 단순한 접근 외에 부가적인 작업 수행
▣ 참여객체
- Proxy : 실제로 참조할 대상에 대한 참조자를 관리한다. Subject 와 동일한 인터페이스를 제공하여 실제 대상을 대체할 수 있어야 한다. 실제 대상에 대한 접근을 제어하고 실제 대상의 생성과 삭제를 책임진다.
- Subject : RealSubject와 Proxy에 공통적인 인터페이스를 정의하고 있어, RealSubject가 요청되는 곳에 Proxy를 사용할 수 있게 한다.
- RealSubject : 프록시가 대표하는 실제 객체

14

Interpreter

▣ 정의
- 간단한 언어의 문법을 정의하는 방법과 그 언어로 문장을 구성하는 방법, 문장을 해석하는 방법을 제시
▣ 활용
- 해석이 필요한 언어가 존재하거나 추상구문트리로 언어에 정의된 문장을 표현하고자 할 때
- 정의할 언어 문법이 간단하고, 효율성은 큰 고려 사항이 아닐 때
▣ 결과
- 문법의 변경과 확장 및 구현 용이
- 표현식을 해석하는 새로운 방법 추가 가능
▣ 참여객체
- AbstractExpression(I/F) : 추상 구문 트리에 속한 모든 노드에 해당하는 클래스들이 공통으로 가져야 할 Interpret() 오퍼레이션을 추상 오퍼레이션으로 정의한다.
- TerminalExpression(C) : 문법에 정의한 터미널 기호와 관련된 해석 방법을 구현한다. 문장을 구성하는 모든 터미널 기호에 대해서 해당 클래스를 만들어야 한다.
- NonTerminalExpression(C) : 문법의 오른편에 나타나는 모든 기호에 대해서 클래스를 정의해야 한다.
- Context : 번역기에 대한 포괄적인 정보를 포함한다.
- Client : 언어로 정의한 특정 문장을 나타내는 추상 구문 트리이다. 이 추상 구문 트리는 NonterminalExpression 과 TerminalExpression 클래스의 인스턴스로 구성된다.

15

Template Method

▣ 정의
- 상위 클래스에서 처리의 흐름을 정하고 하위 클래스에서 구체적인 내용을 재정의하는 디자인 패턴
- 알고리즘의 개별 단계를 구현하는 방법을 서브클래스에서 결정한다.
▣ 활용
- 알고리즘의 변하지 않는 부분을 한 번 정의하고 다양해질 수 있는 부분을 서브플래스에서 정의할 수 있도록 구현하고자 할 때
- 서브클래스 사이의 공통적인 행위를 추출해 하나의 공통클래스로 정의할 때, 이는 일반화를 위한 refactoring의 예라 볼 수 있다. 차이를 보이는 부분을 템플릿 메소드로 정의하고, 나중에 상속받은 서브클래스가 정의하는 오퍼레이션을 호출하게 한다.
- 서브클래스의 확장을 제어할 수 있다. 이는 템플릿 메소드가 어떤 특정한 시점에 hook 오퍼레이션을 호출하도록 정의하면, 실제로 이 hook 오퍼레이션이 호출되는 순간 새로운 확장이 이루어진다.
▣ 결과
- 코드 재사용을 위한 기본 기술이다.
- "할리우드 제어 구조"를 만들어 내기도 하는데, 이는 "전화하지 마세요. 제가 전화할게요" 이다. 이를 클래스에 적용하면, 부모 클래스는 서브클래스에 정의된 오퍼레이션을 호출할 수 있지만 반대로는 되지 않는다.
▣ 참여객체
- AbstractClass(A) : 서브클래스들이 반드시 구현해야 하는 알고리즘 처리 단계 내의 기본 오퍼레이션이 무엇인지를 정의한다.
- ConcreteClass(C) : 서브클래스 마다 기본 오퍼레이션을 다르게 구현한다.

16

Chain of Responsibility

▣ 정의
- 어떠한 요구가 발생 했을때 그 요구를 처리할 객체를 바로 결정 할 수 없는 경우에는 다수의 객체를 사슬처럼 연결해 두고 객체의 사슬을 차례로 돌아다니면서 목적에 맞는 객체를 결정하는 패턴
▣ 활용
- 하나 이상의 객체가 요청을 처리해야 하는 경우, 핸들러가 누가 선행자인지를 모를 때, 다음 핸들러는 자동으로 결정된다.
- 메시지를 받는 객체를 명시하지 않은 채 여러 객체 중 하나에게 처리를 요청하고 싶을 때
- 요청을 처리할 객체 집합을 동적으로 정의하고자 할 때
▣ 결과
- 객체들 간 결합도가 낮아진다.
- 객체에게 책임성을 할당하는 데 있어 응용력을 높일 수 있다.
- 메시지 수신을 보장할 수 없다.
▣ 참여객체
- Handler(A)(Successor) : 자기 자신 호출
- ConcreteHandler(C) : 헨들러 구현

17

Command

▣ 정의
- 명령을 클래스로 만드는 패턴
▣ 활용
- 수행할 행위 자체를 객체로 파라미터화하고자 할때
- 서로 다른 시간에 요청을 명시하고, 저장하고, 수행할 수 있다
- 명령어 객체 자체에 실행 취소에 필요한 상태를 저장할 수 있다
- 변경 과정에 대한 로그를 남겨두면 시스템 고장시 원상태로 복구가 가능하다
- 기본적인 오퍼레이션 조합으로 고난도의 오퍼레이션 구성 가능
▣ 결과
- 오퍼레이션을 호출하는 객체와 오퍼레이션 수행 방법을 구현하는 객체를 분리
- Command 자체도 클래스로서 다른 객체와 같은 방식으로 조작되고 확장 가능
- 명령어를 조합해서 다른 명령어를 만들 수 있다
- 새로운 명령어 추가가 쉽다 (새로운 명령어에 대한 클래스만 정의)
▣ 참여객체
- Command(A) : 오퍼레이션 수행에 필요한 인터페이스 선언
- ConcreteCommand(C)(Asssociation Receiver) : Receiver 객체와 Action 간 바인딩을 정의, 처리객체에 정의된 오퍼레이션을 호출하도록 execute()를 구현
- Client : ConcreteCommand 객체를 생성하고 그것의 receiver를 세팅함
- Invoker(C)(Aggregation Command) : 요청(request)을 처리할 명령어를 요청(ask)
- Receiver(C) : 요청을 처리하는데 관련된 오퍼레이션 수행방법을 알고 있음

18

Iterator

▣ 정의
- 컬렉션이 어떤식으로 구현되었는지 드러내진 않으면서도 컬렉션 내에 있는 모든 객체에 대해 반복 작업을 처리 할 수 있도록 하는 패턴
▣ 활용
- 객체 내부 표현 방식을 몰라도 집합 객체의 각 요소를 순회할 수 있다.
- 서로 다른 집합 객체 구조에 대해서도 동일한 방법으로 순회할 수 있다.
▣ 결과
- Iterator는 Aggregate 클래스의 인터페이스를 단순화 할 수 있다
▣ 참여객체
- Aggregate(I/F) : Iterator 객체를 생성하는 인터페이스를 정의
- Iterator(I/F) : 요소를 접근하고 순회하는데 필요한 인터페이스 제공
- ConcreteIterator(C)(Association ConcreteAggregate) : Iterator에 정의된 인터페이스를 구현하는 클래스로서 순회 과정 중에 집합 객체 내의 현재 위치를 기억한다.
- ConcreteAggregate(C)(Dependency ConcreteIterator) : 해당하는 ConcreteIterator 의 인스턴스를 반환하도록 Iterator 생성 인터페이스를 구현한다.

19

Mediator

▣ 정의
- 마치 카운셀러 처럼 각 멤버로 부터 올라온 보고를 토대로 대국적인 판단을 해서 각 멤버에게 지시를 내리는 패턴
▣ 활용
- 서로 관련된 객체 사이의 복잡한 통신과 제어를 한 곳으로 집중시키고자 하는 경우 사용
- 여러 객체가 잘 정의된 형태이나 복잡한 상호 작용을 하는 경우, 객체들간의 의존성을 잘 이해하기 어려울 때
- 객체의 재사용이 다른 객체와의 연결관계의 복잡함으로 인해 방해를 받을 때
- 여러 클래스에 분산된 행위들이 상속없이 수정되어야 할 때
▣ 결과
- 서브 클래스 수를 제한한다.
- Colleague 들 사이의 종속성을 줄인다.
- 객체의 프로토콜을 단순화하는 장점이 있다.
- 객체들 간의 협력 방법을 하나의 클래스로 추상화한다.
- 통제의 집중화가 이루어진다 (Mediator 클래스 자체의 유지보수가 어려워질 수 있다)
▣ 참여객체
- Colleague(I/F) : Mediator 객체가 누구인지를 안다. 다른 객체와 연결성이 필요하면 Mediator를 통해 이루어지도록 한다.
- ConcreteColleague(C) : Colleague 구현
- Mediator(A)(Aggregate Colleague) : Colleague 객체와 교류하는데 필요한 인터페이스를 정의한다.
- ConcreteMediator(C)(Dependency ConcreteColleague) : Colleague 객체와 조화를 이룸으로써 이루어지는 협력 행위를 구현하고 자신의 Colleague가 무엇인지를 알고 이를 관리한다.

20

Memento

▣ 정의
- 상태를 보존한다.
- 어떤 시점에서의 인스턴스의 상태를 기록해서 저장해 두었다가 나중에 인스턴스를 그 시점의 상태로 되돌리는 패턴
▣ 활용
- 각 시점에서의 객체 상태를 저장한 후 나중에 이 상태로 복구해야 할 때 (Undo)
- 상태를 얻는데 필요한 직접 인터페이스는 객체의 자세한 구현 내용을 드러나게 하고 객체의 캡슐화를 위배하는 것이므로 이를 해결 할 때
▣ 결과
- 캡슐화된 경계를 유지할 수 있다.
- Originator 클래스를 단순화할 수 있다. (Originator 가 다양한 버전의 내부 상태를 모두 저장하고 있어야 하나 클라이언트가 자신이 필요한 상태를 별도로 관리하게 되면 Originator 가 간단해지고, 상태를 변경할 때마다 클라이언트는 Originator 에게 이를 알려줄 필요도 없다.)
- Originator 가 많은 양의 정보를 저장하거나 자주 Memento를 교환해야 할 경우 상당한 오버헤드 가능
- 좁은 범위의 인터페이스와 넓은 범위의 인터페이스를 정의해야 한다.
▣ 참여객체
- Memento
• Memento는 Originator 객체의 내부 상태를 필요한 만큼 저장해 둔다.
• Originator 객체를 제외한 다른 객체는 Memento 클래스에 접근할 수 없다. 그래서 Memento 클래스는 두 개의 인터페이스를 갖는다.
• 관리 책임을 갖는 객체인 CareTaker 클래스는 Memento 에 정의된 모든 인터페이스를 다 보지 못하고 단지 Memento를 다른 객체에 전달한다.
• 이에 비해 Originator 클래스는 자신의 상태를 이전 상태로 복구하기 위해 필요한 모든 자료에 접근하는데 필요한 Memento의 다양한 인터페이스를 사용할 수 있다.
• 즉, Memento를 생성하는 Originator 클래스만이 Memento의 내부상태에 접근할 수 있는 권한을 갖는다.
- Originator(Dependency Memento) : Memento를 생성하여 현재 객체의 상태를 저장하고 내부 상태를 복구한다.
- CareTaker(Aggregate Memento) : Memento의 보관을 책임지기는 하지만, Memento의 내용을 확인하거나 처리하지는 않는다.

21

Observer

▣ 정의
- 관찰대상의 상태가 변하면 관찰자에게 통지되는 패턴
- 상태 변화에 따른 처리를 기술할때 유효함 (엑셀 스프레드시트)
- 자바에서 지원하는 java.util.Observer 가 있으며 푸시(subject 가 보내는), 풀(Observer에서 Observerable 객체로부터 원하는 데이터를 가져오는 방식) 이 있다.
▣ 활용
- 다른 객체에 변화를 통보할 때, 변화에 관심있어 하는 객체들이 누구인가에 대한 가정없이 이루어져야 할 때
▣ 결과
- 대상과 관찰자 모두를 독립적으로 변형하기 쉽다.
- Subject 와 Observer 클래스 간에는 추상화된 결합도만 존재한다.
- Broadcast 방식의 교류를 가능하게 한다.
- 예측하지 못한 수정이 발생할 수 있다. (관찰자가 무엇이 변했는지를 알 수 있게 하는 추가적인 프로토콜 없이는 변경 유추가 매우 어렵다.)
▣ 참여객체
- Subject(A) : for all Observer Update()
- ConcreteSubject(C) : return subjectState
- Observer(A) : update()
- ConcreteObserver(C) : subject->GetState()

22

State

▣ 정의
- 상태를 클래스로 표현하는 패턴, TCP 연결 프로토콜
- 상태를 기반으로 한 행동을 캡슐화 한 다음 위임을 통해서 필요한 행동을 선택 한다.
▣ 활용
- 객체의 상태에 따라 런타임시에 행위가 바뀌어야 할 때
- 객체의 상태에 따라 수많은 조건 문장을 갖도록 오퍼레이션을 구현할 수 있는데, 어떤 경우는 동일한 조건 문장을 하나 이상의 오퍼레이션에 중복 정의해야 할 수도 있다. 이때 객체의 상태를 별도의 객체로 정의함으로써 행위는 다른 객체와 상관없이 다양화 될 수 있다.
▣ 결과
- 상태에 따른 행위를 국지화해 서로 다른 상태에 대한 행위를 별도의 객체로 관리한다. (클래스 수가 많아질 수 있다)
- 상태 전이 규칙을 명확하게 한다. (context 객체가 모순되는 상태를 막을 수 있다)
- 상태 객체는 공유할 수 있다
▣ 참여객체
- Context(C)(Aggregate State) : state->Handler()
- State(A) : Handle()
- ConcreteState(C) : Handle()

23

Strategy

▣ 정의
- 알고리즘을 교체해서 동일한 문제를 다른 방법으로 해결하는 패턴
- 알고리즘 군을 정의하고 각각을 캡슐화하여 바꿔 쓸 수 있게 만듦
- 레지스터 할당 방법, 명령어 집합 스케쥴링 전략
▣ 활용
- 행위들이 조금씩 다를 뿐 개념적으로 관련된 많은 클래스들이 존재하는 경우, 각각의 서로 다른 행위별로 클래스를 작성한다. 즉, 개념에 해당하는 클래스는 하나만 정의하고 서로 다른 행위들을 별도의 클래스로 만드는 것이다.
- 알고리즘의 변형이 필요한 경우에 사용할 수 있다.
- 사용자가 모르고 있는 데이터를 사용해야 하는 알고리즘이 필요할 때
- 많은 행위를 정의하기 위해 클래스 안에 복잡한 다중 조건문을 사용해야 하는 경우 선택문보다는 Strategy 클래스 이용이 바람직
▣ 결과
- 관련 알고리즘의 군을 형성한다. 상속을 통해 알고리즘 공통의 기능성을 추출하고 재사용할 수 있다.
- 서브클래싱을 사용하지 않는 다른 방법이다. 상속은 다양한 알고리즘이나 행위를 지원하는 또 다른 방법이다 (알고리즘을 Strategy 클래스로 독립시키면 Context와 무관하게 알고리즘을 변형/이해/확장이 용이하다.
- Strategy 는 조건문을 없앨 수 있다.
- 구현의 선택이 가능하다 (동일한 행위에 대해 다른 구현을 제공할 수 있다)
- 사용자는 서로 다른 전략을 알고 있어야 한다 (클라이언트가 서로 다른 행위의 특성을 알고 있는 경우 Strategy 사용)
▣ 참여객체
- Strategy(I/F) : 제공하는 모든 알고리즘에 대한 공통의 오퍼레이션들을 인터페이스로 정의한다. Context 클래스는 ConcreteStrategy 클래스에 정의한 인터페이스를 통해서 실제 알고리즘을 사용한다.
- ConcreteStrategy(C) : Strategy 인터페이스를 실제 알고리즘으로 구현한다.
- Context(C)(Aggregate Strategy) : ConcreteStrategy 객체가 무엇인지 구체화한다. 즉, Strategy 객체에 대한 참조자를 관리하고, 실제로는 Strategy 서브클래스의 인스턴스를 갖고 있으므로써 구체화한다. 또한 Strategy 가 자료에 접근해가는데 필요한 인터페이스를 정의한다.

24

Visitor

▣ 정의
- 데이터 구조와 처리를 분리한다. 데이터 구조 안을 돌아다니는 주체인 방문자를 나타내는 클래스를 준비해서 그 클래스에게 처리를 맡긴다. (이벤트 처리, 탐색 등)
- 다양한 객체에 새로운 기능을 추가해야 하는데 캡슐화가 별로 중요하지 않은 경우에는 비지터 패턴을 사용한다.
▣ 활용
- 객제 구조가 다른 인터페이스를 가진 클래스를 포함하고 있어서 구체적 클래스에 따라 오퍼레이션을 수행하고자 할 때
- 구별되고 관련되지 않은 많은 오퍼레이션이 객체에 수행될 필요가 있지만, 오퍼레이션으로 인해 클래스들을 복잡하게 하고 싶지 않을 때.
- Visitor 클래스는 하나의 클래스에 관련되지 않은 모든 오퍼레이션을 함께 정의함으로써, 오퍼레이션을 유지시킨다.
- 객체의 구조가 많은 어플리케이션에 의해 공유될 때 Visitor 클래스를 사용해 필요한 애플리케이션에만 오퍼레이션을 둔다.
▣ 결과
- Visitor 클래스는 새로운 오퍼레이션을 쉽게 추가한다. (방문자를 추가하면 객체 구조에 대한 새로운 오퍼레이션을 추가한 것이 된다.)
- 방문자를 통해 관련된 오퍼레이션을 하나로 모아 관련되지 않은 오퍼레이션과 분리할 수 있다.
- 새로운 ConcreteElement 클래스를 추가하기는 어렵다. (객체의 구조에 적용될 알고리즘의 변화가 자주 발생하거나 이같은 구조를 구성하는 객체 클래스에 변화가 자주 발생할 때 적용한다.)
- 클래스 계층 구조에 걸친 방문 (Iterator 는 Item 타입의 객체만을 관리할 수 있어 서로 다른 종류의 요소를 갖는 구조체를 탐색하지 못한다. 그러나 Visitor 객체는 동일한 부모 클래스가 아니어도 객체 구조를 순회할 수 있다.)
- 상태를 누적할 수 있다 (객체 구조 내의 각 원소를 방문할 때 상태를 누적할 수 있다.)
- 캡슐화 전략을 위배할 수 있다 (요소의 내부 상태에 접근하는 데 필요한 오퍼레이션들을 모두 공개 인터페이스로 만들것을 강요하게 되므로.)
▣ 참여객체
- Visitor(I/F) : 각 ConcreteElement 클래스에 대한 Visit 오퍼레이션을 선언한다. 오퍼레이션의 이름과 인터페이스 형태는 Visit() 요청을 보내는 방문자에게, 보내는 클래스를 명시한다. 이로써 방문자는 방문할 요소의 실제 서브클래스를 결정한다. 그리고 나서 방문자는 Element가 제공하는 인터페이스를 통해 직접 Element 객체에 접근할 수 있다.
- ConcreteVisitor : Visitor 클래스에 정의된 오퍼레이션을 구현한다. 각 오퍼레이션은 객체에 해당하는 클래스에 정의된 알고리즘을 구현한다. ConcreteVisitor 클래스는 내부 상태를 저장하고 있으며, 알고리즘이 운영될 수 있는 상황 정보를 제공한다. ConcreteVisitor 클래스가 저장하고 있는 내부 상태는 구조의 순회 과정에서 도출되기도 한다.
- ObjectStructure : 요소들을 나열하고 방문자로 하여금 이들 요소에 접근하게 하는 인터페이스를 제공한다. ObjectStructure 는 Composite 패턴의 복합 객체일 수도 있고, 리스트나 집합과 같은 컬렉션일 수도 있다.
- Element(I/F) : 아큐먼트로 Visitor 클래스를 받아들이는 Accept() 오퍼레이션을 정의한다.
- ConcreteElement : 아큐먼트로 Visitor 객체를 받아들이는 Accept() 오퍼레이션을 구현한다.