디자인 패턴

eunsiver·2023년 5월 20일
0

디자인 패턴은 프로그램을 개발하는 과정에서 빈번하게 발생하는 디자인 문제를 정리해서 상황에 따라 간편하게 적용할 수 있게 정리한 것입니다. 잘 활용할 수만 있다면 적지 않은 시간과 노력, 시행착오를 줄일 수 있습니다.

모든 패턴은 패턴의 의도 또는 목적에 따라 분류할 수 있습니다.

  • 생성 패턴들은 기존 코드의 재활용과 유연성을 증가시키는 객체 생성 메커니즘들을 제공합니다.

  • 구조 패턴은 구조를 유연하고 효율적으로 유지하면서 객체와 클래스를 더 큰 구조로 조합하는 방법을 설명합니다.

  • 행동 패턴은 객체 간의 효과적인 의사소통과 책임 할당을 처리합니다.

디자인 패턴 요약

🚩 생성

1) Builder : 생산 단계를 캡슐화 하여 구축 공정을 동일하게 이용하도록 하는 패턴
2) Prototype : 복사하여 새 개체를 생성할 수 있도록 하는 패턴
3) Factory Method : 객체를 생성하기 위한 인터페이스를 정의하여 어떤 클래스가 인스턴스화 될 것인지는 서브 클래스가 결정하도록 하는 패턴
4) Abstract Method : 생성군들을 하나의 모아놓고 팩토리 중에서 선택하게 하는 패턴
5) Singleton : 유일한 하나의 인스턴스를 보장하도록 하는 패턴

🚩 구조

1) Bridge : 추상과 구현을 분리하여 결합도를 낮춘 패턴
2) Decorator : 소스를 변경하지 않고 기능을 확장하도록 하는 패턴
3) Facade : 하나의 인터페이스를 통해 느슨한 결합을 제공하는 패턴
4) Flyweight : 대량의 작은 객체들을 공유하는 패턴
5) Proxy : 대리인이 대신 그 일을 처리하는 패턴
6) Composite : 개별 객체와 복합 객체를 클라이언트에서 동일하게 사용하도록 하는 패턴
7) Adapter : 인터페이스로 인해 함께 사용하지 못하는 클래스를 함께 사용하도록 하는 패턴

🚩 행위

1) Interpreter : 언어 규칙 클래스를 이용하는 패턴
2) Template Method : 알고리즘 골격의 구조를 정의한 패턴
3) Chain of Responsibility : 객체들끼리 연결 고리를 만들어 내부적으로 전달하는 패턴
4) Command : 요청 자체를 캡슐화하여 파라미터로 넘기는 패턴
5) Iterator : 내부 표현은 보여주지 않고 순회하는 패턴
6) Mediator : 객체 간 상호작용을 캡슐화한 패턴
7) Memento : 상태 값을 미리 저장해 두었다가 복구하는 패턴
8) Observer : 상태가 변할 때 의존자들에게 알리고, 자동 업데이트하는 패턴
9) State : 객체 내부 상태에 따라서 행위를 변경하는 패턴
10) Strategy : 다양한 알고리즘 캡슐화하여 알고리즘 대체가 가능하도록 한 패턴
11) Visitor : 오퍼레이션을 별도의 클래스에 새롭게 정의한 패턴

디자인 패턴 종류

1. 생성 패턴

Builder

  • 복잡한 객체들을 단계별로 생성할 수 있도록 하는 생성 디자인 패턴입니다. 이 패턴을 사용하면 같은 제작 코드를 사용하여 객체의 다양한 유형들과 표현을 제작할 수 있습니다.

적용

  • 점층적 생성자'를 제거하기 위하여 빌더 패턴을 사용하세요.

  • 빌더 패턴을 사용하면 실제로 필요한 단계들만 사용하여 단계별로 객체들을 생성할 수 있으며, 패턴을 구현한 후에는 더 이상 수십 개의 매개변수를 생성자에 집어넣을 필요가 없습니다.

  • 빌더 패턴은 제품의 다양한 표현의 생성 과정이 세부 사항만 다른 유사한 단계를 포함할 때 적용할 수 있습니다.

  • 빌더는 생성 단계들을 수행하는 동안 미완성 제품을 노출하지 않으며, 이는 클라이언트 코드가 불완전한 결과를 가져오는 것을 방지합니다.


Prototype

  • 처음부터 일반적인 원형을 만들어 놓고, 그것을 복사한 후 필요한 부분만 수정하여 사용하는 패턴
  • 코드를 그들의 클래스들에 의존시키지 않고 기존 객체들을 복사할 수 있도록 하는 생성 디자인 패턴입니다.

적용

당신의 객체들에 수십 개의 필드와 수백 개의 가능한 설정들이 있는 경우 이를 복제하는 것이 서브클래싱의 대안이 될 수 있습니다.

프로토타이핑은 다음과 같이 작동합니다. 일단, 다양한 방식으로 설정된 객체들의 집합을 만듭니다. 그 후 설정한 것과 비슷한 객체가 필요할 경우 처음부터 새 객체를 생성하는 대신 프로토타입을 복제하면 됩니다.

  • 프로토타입 패턴은 복사해야 하는 객체들의 구상 클래스들에 코드가 의존하면 안 될 때 사용하세요.

    • 프로토타입 패턴은 클라이언트 코드에 복제를 지원하는 모든 객체와 작업할 수 있도록 일반 인터페이스를 제공합니다. 이 인터페이스는 클라이언트 코드가 복제하는 객체들의 구상 클래스들에서 클라이언트 코드를 독립시킵니다.
  • 프로토타입 패턴은 각자의 객체를 초기화하는 방식만 다른 자식 클래스들의 수를 줄이고 싶을 때 사용하세요.

    • 프로토타입 패턴은 다양한 방식으로 설정된 미리 만들어진 객체들의 집합을 프로토타입들로 사용할 수 있도록 합니다. 일부 설정과 일치하는 자식 클래스를 인스턴스화하는 대신 클라이언트는 간단하게 적절한 프로토타입을 찾아 복제할 수 있습니다.


Factory Method

부모 클래스에서 객체들을 생성할 수 있는 인터페이스를 제공하지만, 자식 클래스들이 생성될 객체들의 유형을 변경할 수 있도록 하는 생성 패턴입니다.

적용

  • 팩토리 메서드는 당신의 코드가 함께 작동해야 하는 객체들의 정확한 유형들과 의존관계들을 미리 모르는 경우 사용하세요.

    • 예를 들어, 앱에 새로운 제품을 추가하려면 당신은 새로운 크리에이터 자식 클래스를 생성한 후 해당 클래스 내부의 팩토리 메서드를 오버라이딩​(재정의)​하기만 하면 됩니다.
  • 팩토리 메서드는 당신의 라이브러리 또는 프레임워크의 사용자들에게 내부 컴포넌트들을 확장하는 방법을 제공하고 싶을 때 사용하세요.

  • 팩토리 메서드는 기존 객체들을 매번 재구축하는 대신 이들을 재사용하여 시스템 리소스를 절약하고 싶을 때 사용하세요.


Abstract Factory

  • 관련 객체들의 구상 클래스들을 지정하지 않고도 관련 객체들의 모음을 생성할 수 있도록 하는 생성패턴입니다.

적용

  • 추상 팩토리는 당신의 코드가 관련된 제품군의 다양한 패밀리들과 작동해야 하지만 해당 제품들의 구상 클래스들에 의존하고 싶지 않을 때 사용하세요. 왜냐하면 이러한 클래스들은 당신에게 미리 알려지지 않았을 수 있으며, 그 때문에 향후 확장성​(extensibility)​을 허용하기를 원할 수 있기 때문입니다.

    • 추상 팩토리는 제품 패밀리의 각 클래스에서부터 객체들을 생성할 수 있는 인터페이스를 제공합니다. 위 인터페이스를 통해 코드가 객체들을 생성하는 한 당신은 당신의 앱에서 이미 생성된 제품들과 일치하지 않는 잘못된 제품 변형을 생성하지 않을지 걱정할 필요가 없습니다.

Singleton

클래스에 인스턴스가 하나만 있도록 하면서 이 인스턴스에 대한 전역 접근​(액세스) 지점을 제공하는 생성 디자인 패턴입니다.

정부는 싱글턴 패턴의 훌륭한 예입니다. 국가는 하나의 공식 정부만 가질 수 있습니다. 그리고 'X의 정부'라는 명칭은 정부를 구성하는 개인들의 신원과 관계없이 정부 책임자들의 그룹을 식별하는 글로벌 접근 지점입니다.

싱글턴 클래스는 정적 메서드 get­Instance를 선언합니다. 이 메서드는 자체 클래스의 같은 인스턴스를 반환합니다.

싱글턴의 생성자는 항상 클라이언트 코드에서부터 숨겨져야 합니다. get­Instance 메서드를 호출하는 것이 Singleton 객체를 가져올 수 있는 유일한 방법이어야 합니다.

적용

  • 싱글턴 패턴은 당신 프로그램의 클래스에 모든 클라이언트가 사용할 수 있는 단일 인스턴스만 있어야 할 때 사용하세요. 예를 들자면 프로그램의 다른 부분들에서 공유되는 단일 데이터베이스 객체처럼 말입니다.

  • 싱글턴 패턴은 전역 변수들을 더 엄격하게 제어해야 할 때 사용하세요.


2. 구조 패턴

Bridge

큰 클래스 또는 밀접하게 관련된 클래스들의 집합을 두 개의 개별 계층구조​(추상화 및 구현)​로 나눈 후 각각 독립적으로 개발할 수 있도록 하는 구조 디자인 패턴입니다.


기초 리모컨 클래스는 이 클래스를 장치 객체와 연결하는 참조 필드를 선언합니다. 모든 리모컨은 일반 장치 인터페이스를 통해 장치들과 작동하므로 같은 리모컨이 여러 장치 유형을 지원할 수 있습니다.

장치 클래스들과 독립적으로 리모컨 클래스들을 개발할 수 있으며, 필요한 것은 새로운 리모컨 자식 클래스를 만드는 것뿐입니다. 예를 들어 기초 리모컨에는 버튼이 두 개뿐일 수 있지만, 추가 터치스크린과 추가 배터리 같은 기능들도 가지도록 확장할 수 있습니다.


Decorator

  • 객체들을 새로운 행동들을 포함한 특수 래퍼 객체들 내에 넣어서 위 행동들을 해당 객체들에 연결시키는 구조적 디자인 패턴입니다.

  • 객체의 결합 을 통해 기능을 동적으로 유연하게 확장 할 수 있게 해주는 패턴

    • 즉, 기본 기능에 추가할 수 있는 기능의 종류가 많은 경우에 각 추가 기능을 Decorator 클래스로 정의 한 후 필요한 Decorator 객체를 조합함으로써 추가 기능의 조합을 설계 하는 방식이다.


Facade

  • 라이브러리에 대한, 프레임워크에 대한 또는 다른 클래스들의 복잡한 집합에 대한 단순화된 인터페이스를 제공하는 구조적 디자인 패턴입니다.

전화로 주문하기

전화로 주문하기 위해 매장에 전화를 걸었을 때 전화를 받는 교환원이 바로 상점의 모든 서비스와 부서에 대한 당신의 퍼사드입니다. 이때 교환원은 주문 시스템, 지불 게이트웨이 및 다양한 배송 서비스에 대한 간단한 음성 인터페이스를 제공합니다.

구조

  1. 퍼사드 패턴을 사용하면 하위 시스템 기능들의 특정 부분에 편리하게 접근할 수 있습니다. 또 퍼사드는 클라이언트의 요청을 어디로 보내야 하는지와 움직이는 모든 부품을 어떻게 작동해야 하는지를 알고 있습니다.

  2. 추가적인 퍼사드 클래스를 생성하여 하나의 퍼사드를 관련 없는 기능들로 오염시켜 복잡한 구조로 만드는 것을 방지할 수 있습니다. 추가 퍼사드들은 클라이언트들과 다른 퍼사드들 모두에 사용할 수 있습니다.

  3. 복잡한 하위 시스템은 수십 개의 다양한 객체들로 구성됩니다. 이 모든 객체가 의미 있는 작업을 수행하도록 하려면, 하위 시스템의 세부적인 구현 정보를 깊이 있게 살펴야 합니다. 예를 들어 올바른 순서로 객체들을 초기화하고 그들에게 적절한 형식의 데이터를 제공하는 등의 작업을 수행해야 합니다.

    하위 시스템 클래스들은 퍼사드의 존재를 인식하지 못합니다. 이들은 시스템 내에서 작동하며, 매개체 없이 직접 서로와 작업합니다.

  4. 클라이언트는 하위 시스템 객체들을 직접 호출하는 대신 퍼사드를 사용합니다.

적용

  • 퍼사드 패턴은 당신이 복잡한 하위 시스템에 대한 제한적이지만 간단한 인터페이스가 필요할 때 사용하세요.

  • 퍼사드 패턴은 하위 시스템을 계층들로 구성하려는 경우 사용하세요.


Flyweight

  • 각 객체에 모든 데이터를 유지하는 대신 여러 객체들 간에 상태의 공통 부분들을 공유하여 사용할 수 있는 RAM에 더 많은 객체들을 포함할 수 있도록 하는 구조 디자인 패턴입니다.

적용

  • 플라이웨이트 패턴은 당신의 프로그램이 많은 수의 객체들을 지원해야 해서 사용할 수 있는 RAM을 거의 다 사용했을 때만 사용하세요.

  • 이 패턴 적용의 혜택은 패턴을 사용하는 방법과 위치에 따라 크게 달라지며, 다음과 같은 경우에 가장 유용합니다.

    • 앱이 수많은 유사 객체들을 생성해야 할 때
    • 이것이 대상 장치에서 사용할 수 있는 모든 RAM을 소모할 때
    • 이 객체들에 여러 중복 상태들이 포함되어 있으며, 이 상태들이 추출된 후 객체 간에 공유될 수 있을 때

Proxy

  • 다른 객체에 대한 대체 또는 자리표시자를 제공할 수 있는 구조 디자인 패턴입니다. 프록시는 원래 객체에 대한 접근을 제어하므로, 당신의 요청이 원래 객체에 전달되기 전 또는 후에 무언가를 수행할 수 있도록 합니다.

적용

프록시 패턴을 활용하는 방법들은 수십 가지가 있으며, 패턴이 가장 많이 사용되는 용도들을 살펴보겠습니다.

  • 지연된 초기화​(가상 프록시)
    이것은 어쩌다 필요한 무거운 서비스 객체가 항상 가동되어 있어 시스템 자원들을 낭비하는 경우입니다.

    앱이 시작될 때 객체를 생성하는 대신, 객체 초기화를 실제로 초기화가 필요한 시점까지 지연할 수 있습니다.

  • 접근 제어 (보호 프록시)
    당신이 특정 클라이언트들만 서비스 객체를 사용할 수 있도록 하려는 경우에 사용할 수 있습니다. 예를 들어 당신의 객체들이 운영 체제의 중요한 부분이고 클라이언트들이 다양한 실행된 응용 프로그램​(악의적인 응용 프로그램 포함)​인 경우입니다.

    이 프록시는 클라이언트의 자격 증명이 어떤 정해진 기준과 일치하는 경우에만 서비스 객체에 요청을 전달할 수 있습니다.

  • 원격 서비스의 로컬 실행 (원격 프록시)
    서비스 객체가 원격 서버에 있는 경우입니다.

    이 경우 프록시는 네트워크를 통해 클라이언트 요청을 전달하여 네트워크와의 작업의 모든 복잡한 세부 사항을 처리합니다.

  • 요청들의 로깅​(로깅 프록시)
    서비스 객체에 대한 요청들의 기록을 유지하려는 경우입니다.

    프록시는 각 요청을 서비스에 전달하기 전에 로깅​(기록)​할 수 있습니다.

  • 요청 결과들의 캐싱​(캐싱 프록시)
    이것은 클라이언트 요청들의 결과들을 캐시하고 이 캐시들의 수명 주기를 관리해야 할 때, 특히 결과들이 상당히 큰 경우에 사용됩니다.

    프록시는 항상 같은 결과를 생성하는 반복 요청들에 대해 캐싱을 구현할 수 있습니다. 프록시는 요청들의 매개변수들을 캐시 키들로 사용할 수 있습니다.

  • 스마트 참조
    이것은 사용하는 클라이언트들이 없어 거대한 객체를 해제할 수 있어야 할 때 사용됩니다.

    프록시는 서비스 객체 또는 그 결과에 대한 참조를 얻은 클라이언트들을 추적할 수 있습니다. 때때로 프록시는 클라이언트들을 점검하여 클라이언트들이 여전히 활성 상태인지를 확인할 수 있습니다. 클라이언트 리스트가 비어 있으면 프록시는 해당 서비스 객체를 닫고 그에 해당하는 시스템 자원을 확보할 수 있습니다.

    또 프록시는 클라이언트가 서비스 객체를 수정했는지도 추적할 수 있으며, 변경되지 않은 객체는 다른 클라이언트들이 재사용할 수 있습니다.


Composite

복합체 패턴은 객체들을 트리 구조들로 구성한 후, 이러한 구조들과 개별 객체들처럼 작업할 수 있도록 하는 구조 패턴입니다.

실제상황 적용

군대 구조의 예시

대부분의 국가에서 군대는 계층구조로 구성되어 있습니다. 군대는 여러 사단으로 구성되며, 사단은 여단의 집합이고, 여단은 소대의 집합이며, 소대는 또 분대로 나누어질 수 있습니다. 마지막으로 분대는 실제 군인들의 작은 집합입니다. 명령들은 계층구조의 최상위에서 내려와 모든 병사가 자신이 수행해야 할 작업을 알게 될 때까지 계층구조의 각 하위 계층으로 전달됩니다.

  1. 컴포넌트 인터페이스는 트리의 단순 요소들과 복잡한 요소들 모두에 공통적인 작업을 설명합니다.

  2. 잎은 트리의 기본 요소이며 하위요소가 없습니다.

    일반적으로 잎 컴포넌트들은 작업을 위임할 하위요소가 없어서 대부분의 실제 작업들을 수행합니다.

  3. 컨테이너(일명 복합체)​는 하위 요소들​(잎 또는 기타 컨테이너)​이 있는 요소입니다. 컨테이너는 자녀들의 구상 클래스들을 알지 못하며, 컴포넌트 인터페이스를 통해서만 모든 하위 요소들과 함께 작동합니다.

    요청을 전달받으면 컨테이너는 작업을 하위 요소들에 위임하고 중간 결과들을 처리한 다음 최종 결과들을 클라이언트에 반환합니다.

  4. 클라이언트는 컴포넌트 인터페이스를 통해 모든 요소들과 작동합니다. 그 결과 클라이언트는 트리의 단순 요소들 또는 복잡한 요소들 모두에 대해 같은 방식으로 작업할 수 있습니다.


Adapter

어댑터는 호환되지 않는 인터페이스를 가진 객체들이 협업할 수 있도록 하는 구조적 디자인 패턴입니다.

적용

  • 어댑터 클래스는 기존 클래스를 사용하고 싶지만 그 인터페이스가 나머지 코드와 호환되지 않을 때 사용하세요.

  • 이 패턴은 부모 클래스에 추가할 수 없는 어떤 공통 기능들이 없는 여러 기존 자식 클래스들을 재사용하려는 경우에 사용하세요.


3. 행위 패턴

Mediator

중재자는 객체 간의 혼란스러운 의존 관계들을 줄일 수 있는 행동 디자인 패턴입니다. 이 패턴은 객체 간의 직접 통신을 제한하고 중재자 객체를 통해서만 협력하도록 합니다.


Interpreter

  • 언어의 다양한 해석, 구체적으로 구문을 나누고 그 분리된 구문의 해석을 맡는 클래스를 각각 작성하여 여러 형태의 언어 구문을 해석할 수 있게 만드는 디자인 패턴
  • 문법 자체를 캡슐화하여 사용

Iterator

반복자는 컬렉션의 요소들의 기본 표현​(리스트, 스택, 트리 등)​을 노출하지 않고 그들을 하나씩 순회할 수 있도록 하는 행동 디자인 패턴입니다.

반복자 패턴의 주 아이디어는 컬렉션의 순회 동작을 반복자라는 별도의 객체로 추출하는 것입니다.

반복자들은 다양한 순회 알고리즘들을 구현합니다. 여러 반복자 객체들이 동시에 같은 컬렉션을 순회할 수 있습니다.

반복자 객체는 알고리즘 자체를 구현하는 것 외에도 모든 순회 세부 정보들​(예: 현재 위치 및 남은 요소들의 수)​을 캡슐화하며, 이 때문에 여러 반복자들이 서로 독립적으로 동시에 같은 컬렉션을 통과할 수 있습니다.

적용

  • 반복자 패턴은 당신의 컬렉션이 내부에 복잡한 데이터 구조가 있지만 이 구조의 복잡성을 보안이나 편의상의 이유로 클라이언트들로부터 숨기고 싶을 때 사용하세요.

    반복자는 복잡한 데이터 구조와 작업 시의 세부 사항을 캡슐화하여 클라이언트에 컬렉션 요소들에 접근할 수 있는 몇 가지 간단한 메서드들을 제공합니다. 이 접근 방식은 클라이언트에게 매우 편리합니다. 또 클라이언트가 컬렉션과 직접 작동할 때 클라이언트가 수행할 수 있는 부주의하거나 악의적인 행동들로부터 컬렉션을 보호합니다.

  • 반복자 패턴을 사용하여 당신의 앱 전체에서 순회 코드의 중복을 줄이세요.

  • 반복자 패턴은 코드가 다른 데이터 구조들을 순회할 수 있기를 원할 때 또는 이러한 구조들의 유형을 미리 알 수 없을 때 사용하세요.


Template Method

  • 템플릿 메서드는 부모 클래스에서 알고리즘의 골격을 정의하지만, 해당 알고리즘의 구조를 변경하지 않고 자식 클래스들이 알고리즘의 특정 단계들을 오버라이드​(재정의)​할 수 있도록 하는 행동 디자인 패턴입니다.


Observer

옵서버 패턴은 당신이 여러 객체에 자신이 관찰 중인 객체에 발생하는 모든 이벤트에 대하여 알리는 구독 메커니즘을 정의할 수 있도록 하는 행동 디자인 패턴입니다.


State

  • 상태 패턴은 객체의 내부 상태가 변경될 때 해당 객체가 그의 행동을 변경할 수 있도록 하는 행동 디자인 패턴입니다. 객체가 행동을 변경할 때 객체가 클래스를 변경한 것처럼 보일 수 있습니다.

실제상황 적용

스마트폰의 버튼들과 스위치들은 장치의 현재 상태에 따라 다르게 행동합니다.

  • 스마트폰이 잠금 해제된 상태에서 버튼들을 누르면 다양한 함수들이 실행됩니다.
  • 스마트폰이 잠긴 상태에서 아무 버튼이나 누르면 항상 잠금 해제 화면이 나타납니다.
  • 스마트폰의 충전량이 적을 때 아무 버튼이나 누르면 충전 화면이 나타납니다.

Visitor

비지터(방문자) 패턴은 알고리즘들을 그들이 작동하는 객체들로부터 분리할 수 있도록 하는 행동 디자인 패턴입니다.

Command

요청을 요청에 대한 모든 정보가 포함된 독립실행형 객체로 변환하는 행동 디자인 패턴입니다. 이 변환은 다양한 요청들이 있는 메서드들을 인수화 할 수 있도록 하며, 요청의 실행을 지연 또는 대기열에 넣을 수 있도록 하고, 또 실행 취소할 수 있는 작업을 지원할 수 있도록 합니다.

실제상황 적용

당신은 도시를 한참 걷다가 멋진 레스토랑에 도착하여 창가 테이블에 앉습니다. 친절한 웨이터가 다가와 신속하게 당신의 주문을 받아 종이에 적습니다. 웨이터는 부엌으로 가서 주문을 벽에 붙입니다. 잠시 후 요리사에게 주문이 전달되고 요리사는 주문을 읽고 그에 따라 음식을 요리합니다. 요리사는 주문과 함께 식사를 트레이에 놓습니다. 웨이터는 트레이를 발견한 후 당신이 주문한 대로 식사가 요리되었는지 확인하고 완성된 주문을 당신의 테이블로 가져옵니다.

종이에 적힌 주문은 커맨드 역할을 합니다. 이 주문은 요리사가 요리할 준비가 될 때까지 대기열에 남아 있습니다. 주문에는 식사를 요리하는 데 필요한 모든 관련 정보가 포함되어 있습니다. 이를 통해 요리사는 당신에게서 주문 세부 사항을 직접 전달받는 대신 바로 요리를 시작할 수 있습니다.

적용

  • 작업들로 객체를 매개변수화하려는 경우 커맨드 패턴을 사용하세요.

  • 커맨드 패턴은 작업들의 실행을 예약하거나, 작업들을 대기열에 넣거나 작업들을 원격으로 실행하려는 경우에 사용하세요.

  • 커맨드 패턴은 되돌릴 수 있는 작업을 구현하려고 할 때 사용하세요.


Strategy

알고리즘들의 패밀리를 정의하고, 각 패밀리를 별도의 클래스에 넣은 후 그들의 객체들을 상호교환할 수 있도록 하는 행동 디자인 패턴입니다.

적용

  • 전략 패턴은 객체 내에서 한 알고리즘의 다양한 변형들을 사용하고 싶을 때, 그리고 런타임 중에 한 알고리즘에서 다른 알고리즘으로 전환하고 싶을 때 사용하세요.

  • 전략 패턴은 일부 행동을 실행하는 방식에서만 차이가 있는 유사한 클래스들이 많은 경우에 사용하세요.

  • 전략 패턴을 사용하여 클래스의 비즈니스 로직을 해당 로직의 콘텍스트에서 그리 중요하지 않을지도 모르는 알고리즘들의 구현 세부 사항들로부터 고립하세요.

  • 이 패턴은 같은 알고리즘의 다른 변형들 사이를 전환하는 거대한 조건문이 당신의 클래스에 있는 경우에 사용하세요.


Memento

객체의 구현 세부 사항을 공개하지 않으면서 해당 객체의 이전 상태를 저장하고 복원할 수 있게 해주는 행동 디자인 패턴입니다.

적용

  • 메멘토는 객체의 이전 상태를 복원할 수 있도록 객체의 상태의 스냅샷들을 생성하려는 경우에 사용하세요.

  • 이 패턴은 또 객체의 필드들/게터들/세터들을 직접 접근하는 것이 해당 객체의 캡슐화를 위반할 때 사용하세요.

Chain of Responsibility

핸들러들의 체인​(사슬)​을 따라 요청을 전달할 수 있게 해주는 행동 디자인 패턴입니다. 각 핸들러는 요청을 받으면 요청을 처리할지 아니면 체인의 다음 핸들러로 전달할지를 결정합니다.

적용

  • 책임 연쇄 패턴은 당신의 프로그램이 다양한 방식으로 다양한 종류의 요청들을 처리할 것으로 예상되지만 정확한 요청 유형들과 순서들을 미리 알 수 없는 경우에 사용하세요.

  • 이 패턴은 특정 순서로 여러 핸들러를 실행해야 할 때 사용하세요.

  • 책임 연쇄 패턴은 핸들러들의 집합과 그들의 순서가 런타임에 변경되어야 할 때 사용하세요.


참고

profile
Let's study!

0개의 댓글