노트

전략 패턴

Strategy

설계#pattern · 연결된 개념 12개

쉽게 말하면

전략 패턴은 카메라에서 인물, 야경, 접사 모드를 골라 끼우는 것과 같아요. 셔터 누르는 법은 그대로고, 새 모드가 생겨도 셔터 버튼을 고칠 필요가 없어요.

비유가 깨지는 곳 모드마다 거창한 클래스가 꼭 필요한 건 아니에요. 일급 함수가 있는 언어에서는 함수 하나로 충분하고, 상태 패턴과 달리 전략은 바깥에서 골라 끼워요.

같은 목적을 가진 여러 알고리즘을 각각 별도 객체(또는 함수)로 빼고, 실행할 때 그중 하나를 골라 끼우는 패턴. 호출하는 쪽은 공통 인터페이스만 안다.

type DiscountStrategy = (price: number) => number
 
const strategies: Record<string, DiscountStrategy> = {
  none: p => p,
  member: p => p * 0.9,
  coupon: p => Math.max(0, p - 3000),
}
 
function checkout(price: number, kind: keyof typeof strategies) {
  return strategies[kind](price)
}
  • 새 할인 방식을 추가할 때 checkout을 고치지 않고 전략만 더한다. 확장에 열리고 수정에 닫힌 구조다(SOLID 원칙의 OCP, Open-Closed Principle)
  • 할인 계산, 정렬 기준, 인증 방식, 렌더링 방식 선택이 전형적인 예다
  • 테스트에서 가짜 전략을 넣기 쉽다
  • 일급 함수가 있는 언어에서는 위처럼 함수 하나로 충분하다. 인터페이스와 클래스 계층을 갖춘 객체 전략은 상태가 필요하거나 메서드가 여럿일 때만 쓴다

비슷한 것들과의 차이

행동 패턴 전체는 행동 패턴.

출처: Strategy — Refactoring.Guru

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 어댑터 패턴

    쓸 수 있는 객체가 있는데 인터페이스가 맞지 않을 때, 중간에서 호출을 받아 실제 객체가 알아듣는 형태로 바꿔 주는 패턴. 전원 플러그 변환기와 같다.

  • 커맨드 패턴

    요청이나 작업을 실행 가능한 객체로 포장하는 패턴. 작업을 값처럼 저장·전달·대기열에 넣을 수 있게 되고, 되돌리기 같은 부가 연산을 붙일 수 있다.

  • 데코레이터 패턴

    같은 인터페이스를 구현한 래퍼로 객체를 감싸, 원래 객체를 고치지 않고 앞뒤에 기능을 덧붙이는 패턴. 래퍼를 여러 겹 쌓아 기능을 조합할 수 있다.

  • 구조 패턴

    클래스와 객체를 조합해 더 큰 구조를 만드는 패턴들. 맞지 않는 인터페이스, 부분과 전체, 기능 덧붙이기, 접근 제어 같은 문제를 다룬다. 상당수가 "같은 인터페이스를 가진 객체로 감싼다"는 같은 모양을 하고 있고, 감싸는 목적이 다르다.

  • 생성 패턴

    객체를 만드는 과정을 감추는 패턴들. 어떤 구체 클래스를 고를지, 생성 단계를 어떻게 보장할지, 생성 비용을 어떻게 줄일지를 다룬다. 호출하는 쪽이 new 구체클래스()를 직접 쓰지 않게 해서 결합도(Coupling)를 낮추는 것이 공통점이다.

보기 옵션