전략 패턴 (Strategy Pattern) for JavaScript

최은우·2023년 4월 13일
0

Design Pattern

목록 보기
4/5
post-thumbnail

전략 패턴

전략 패턴 (또는 정책 패턴)은 객체 지향 디자인 패턴 중 하나로 동일한 문제를 해결하기 위한 여러 알고리즘(전략)을 정의하고, 각각을 캡슐화하여 상호 교환 가능하도록 만드는 패턴입니다.
이를 통해 런타임 시에 알고리즘을 선택하고 적용할 수 있게 됩니다.

예를 들어 여러가지 정렬 알고리즘을 생각해 봅시다.
BubbleSort, QuickSort, InsertionSort 등이 있습니다.
전략 패턴을 사용하면 이러한 정렬 알고리즘을 각각의 전략으로 캡슐화하여 코드를 실행할 때 필요한 전략을 동적으로 선택하여 사용할 수 있게 됩니다.

역시 이해가 어려우니 코드를 보며 살펴봅시다.


// BubbleSortStrategy: 버블 정렬 알고리즘
class BubbleSortStrategy {
  sort(arr) {
    let len = arr.length;
    for (let i = 0; i < len; i++) {
      for (let j = 0; j < len - 1 - i; j++) {
        if (arr[j] > arr[j + 1]) {
          let temp = arr[j + 1];
          arr[j + 1] = arr[j];
          arr[j] = temp;
        }
      }
    }
    return arr;
  }
}

// QuickSortStrategy: 퀵 정렬 알고리즘
class QuickSortStrategy {
  sort(arr) {
    if (arr.length <= 1) {
      return arr;
    }

    let pivotIndex = Math.floor(arr.length / 2);
    let pivot = arr.splice(pivotIndex, 1)[0];

    let left = [];
    let right = [];

    for (let i = 0; i < arr.length; i++) {
      if (arr[i] < pivot) {
        left.push(arr[i]);
      } else {
        right.push(arr[i]);
      }
    }

    return this.sort(left).concat([pivot], this.sort(right));
  }
}

// Sorter: 정렬을 수행하는 클래스
class Sorter {
  constructor(strategy) {
    this.strategy = strategy;
  }

  sort(arr) {
    return this.strategy.sort(arr);
  }
}

// 예시 코드
let arr = [5, 2, 4, 6, 1, 3];

let bubbleSorter = new Sorter(new BubbleSortStrategy());
console.log(bubbleSorter.sort(arr)); // [1, 2, 3, 4, 5, 6]

let quickSorter = new Sorter(new QuickSortStrategy());
console.log(quickSorter.sort(arr)); // [1, 2, 3, 4, 5, 6]

위의 코드에서 Sorter 클래스가 전략 패턴을 구현한 클래스입니다.

Sorter는 생성자에서 전달받은 전략 객체의 sort 메소드를 호출하여 정렬을 수행하게 됩니다.


이제 장 단점들을 살펴보겠습니다.

장점

  1. 유연성: 알고리즘을 도적으로 교환할 수 있어 프로그램의 유연성을 높입니다. 새로운 전략을 추가하거나 기존 전략을 수정하여 알고리즘을 쉽게 변경할 수 있습니다.
  2. 재사용성: 각 전략이 별개의 클래스로 캡슐화되기 때문에 각각의 전략을 재사용할 수 있습니다. 이는 개발 비용과 시간을 절약할 수 있습니다.
  3. 테스트 용이성: 각 전략을 독립적으로 테스트할 수 있기 때문에 테스트가 용이합니다. 각 전략을 개별적으로 테스트하면 오류를 신속하게 발견할 수 있습니다.

단점

  1. 클래스 개수: 각 전략이 별개의 클래스로 캡슐화되기 때문에 클래스의 수가 증가할 수 있습니다. 이는 코드의 복잡성을 높이고 유지보수를 어렵게 만들 수 있습니다.
  2. 오버헤드: 런타임에 전략을 교체하기 때문에 일부 오버헤드가 발생할 수 있습니다. 하지만 대부분의 경우 이 오버헤드는 굉장히 작습니다.

0개의 댓글