Web/JS

[JS] 디자인 패턴(Design Pattern)_전략 패턴(Strategy Pattern)

메바동 2023. 3. 3. 00:07
728x90

"JavaScript Design Pattern" 포스팅은 ChatGPT에게 "Essential design patterns for JavaScript developers to learn"로 질문한 뒤 나온 내용에 대해 정리하는 포스팅입니다.

 


 

1. 전략 패턴(Strategy Pattern)

전략 패턴은 객체 지향 디자인 패턴 중 하나로, 유사한 동작을 수행하는 알고리즘 집합을 정의하고, 이를 동적으로 선택하여 사용하는 방식으로 구현된다.

이 패턴을 사용하면, 알고리즘이 사용하는 행동들을 인터페이스를 통해 분리함으로써, 런타임에 객체가 다른 알고리즘을 선택할 수 있다.

 

전략 패턴은 대게 한 객체에서 알고리즘을 다른 객체로 전환하는 것이다.

Strategy 객체는 다른 객체에서 호출될 수 있는 동일한 메서드를 정의한다. 이 메서드는 일반적으로 'execute'와 같은 이름을 갖는다.

Strategy 객체는 동적으로 구성할 수 있으므로, 전략을 사용하기 위해 if-else 또는 switch-case 문을 사용할 필요가 없다. 대신에, 적합한 Strategy 객체를 선택하여 호출하면 된다.

 

전력 패턴은 주로 특정 작업을 수행하기 위해 다양한 알고리즘을 사용하는 경우 유용하다.

예를 들어, 여러 가지 정렬 알고리즘이 있을 때, 전략 패턴을 사용하여 적절한 정렬 알고리즘을 선택할 수 있다.

이를 통해 적합한 알고리즘을 사용하여 더 높은 성능을 얻을 수 있다.

 

전략 패턴은 크게 3가지 요소로 구성된다.

 

  1. Context: Strategy 객체를 사용하는 역할을 수행하며, Strategy 객체를 외부에서 주입받아 사용한다.
  2. Strategy: 유사한 동작을 수행하는 알고리즘 집합을 정의하고, Context에서 주입받아 실행한다.
  3. ConcreteStrategy: Strategy 인터페이스를 구현한 구체적인 알고리즘 집합이다.

 

다음은 JavaScript에서 전략 패턴을 구현한 예이다:

 

// Define a strategy interface
class SortStrategy {
  sort(array) {}
}

// Define concrete sorting strategies
class BubbleSortStrategy extends SortStrategy {
  sort(array) {
    console.log('Sorting using Bubble Sort');
    // Implement Bubble Sort algorithm here
    return array;
  }
}

class QuickSortStrategy extends SortStrategy {
  sort(array) {
    console.log('Sorting using Quick Sort');
    // Implement Quick Sort algorithm here
    return array;
  }
}

// Define a context that uses the strategy
class Sorter {
  constructor(strategy) {
    this.strategy = strategy;
  }

  setStrategy(strategy) {
    this.strategy = strategy;
  }

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

// Usage:
const array = [5, 1, 4, 2, 8];
const bubbleSortStrategy = new BubbleSortStrategy();
const quickSortStrategy = new QuickSortStrategy();

const sorter = new Sorter(bubbleSortStrategy);
console.log(sorter.sort(array)); // Output: Sorting using Bubble Sort [5, 1, 4, 2, 8]

sorter.setStrategy(quickSortStrategy);
console.log(sorter.sort(array)); // Output: Sorting using Quick Sort [5, 1, 4, 2, 8]

 

이 예제에서는 sort()라는 단일 메서드가 있는 SortStrategy 인터페이스를 정의한다.

그런 다음 sort() 메서드를 구현하는 두 개의 구체적인 전략 BubbleSortStrategy와 QuickSortStrategy를 생성한다.

 

다음으로, 생성자에서 SortStrategy 객체를 취하고 런타임에 정렬 알고리즘을 변경하는 setStrategy() 메서드가 이
는 Sorter 클래스를 정의한다.

Sorter 클래스의 sort() 메서드는 정렬 책임을 현재 SortStrategy 객체에 위임한다.

 

마지막으로 배열과 두 가지 정렬 전략인 BubbleSortStrategy와 QuickSortStrategy를 생성한다. 그런 다음 Sorter 클래스를 사용하여 두 전략을 모두 사용하여 배열을 정렬하고, setStrategy() 메서드를 사용하여 현재 정렬 알고리즘을 설정하고 sort() 메서드를 호출한다.

 

전략 패턴을 사용하면 새로운 정렬 알고리즘이 추가되더라도 Sorter 클래스를 변경하지 않고 쉽게 추가할 수 있다.

 

 

 

2. Strategy Pattern 연습 코드

ChatGPT에게 "Give me a challenge to practice the Strategy Pattern in JavaScript."라고 질문한 뒤 나온 문제와 그에 대한 답이다.

 

스켈레톤 코드는 다음과 같다.

 

class SortStrategy {
  // SortStrategy 클래스의 코드를 작성하세요.
}

class LongStringSortStrategy extends SortStrategy {
  // LongStringSortStrategy 클래스의 코드를 작성하세요.
}

class ShortStringSortStrategy extends SortStrategy {
  // ShortStringSortStrategy 클래스의 코드를 작성하세요.
}

class StringSorter {
  constructor(sortStrategy) {
    this.sortStrategy = sortStrategy;
  }

  setSortStrategy(sortStrategy) {
    this.sortStrategy = sortStrategy;
  }

  sortStrings(strings) {
    // 전달된 문자열 배열을 정렬하는 코드를 작성하세요.
  }
}

// 사용자 입력을 받는 코드
const strings = ['apple', 'banana', 'cherry', 'date', 'elderberry'];
const userInput = prompt('Do you want to see long strings first? (y/n)');
let sortStrategy;
if (userInput.toLowerCase() === 'y') {
  sortStrategy = new LongStringSortStrategy();
} else {
  sortStrategy = new ShortStringSortStrategy();
}
const stringSorter = new StringSorter(sortStrategy);
stringSorter.sortStrings(strings);

 

이를 구현한 코드는 다음과 같다.

 

class SortStrategy {
  // SortStrategy 클래스의 코드를 작성하세요.
  sort(strings) {}
}

class LongStringSortStrategy extends SortStrategy {
  // LongStringSortStrategy 클래스의 코드를 작성하세요.
  sort(strings) {
    return strings.sort((first, second) => second.length - first.length);
  }
}

class ShortStringSortStrategy extends SortStrategy {
  // ShortStringSortStrategy 클래스의 코드를 작성하세요.
  sort(strings) {
    return strings.sort((first, second) => first.length - second.length);
  }
}

class StringSorter {
  constructor(sortStrategy) {
    this.sortStrategy = sortStrategy;
  }

  setSortStrategy(sortStrategy) {
    this.sortStrategy = sortStrategy;
  }

  sortStrings(strings) {
    // 전달된 문자열 배열을 정렬하는 코드를 작성하세요.
    return this.sortStrategy.sort(strings);
  }
}

// 사용자 입력을 받는 코드
const strings = ['apple', 'banana', 'cherry', 'date', 'elderberry'];
const userInput = prompt('Do you want to see long strings first? (y/n)');
let sortStrategy;
if (userInput.toLowerCase() === 'y') {
  sortStrategy = new LongStringSortStrategy();
} else {
  sortStrategy = new ShortStringSortStrategy();
}
const stringSorter = new StringSorter(sortStrategy);
const sortedStrings = stringSorter.sortStrings(strings);
console.log(sortedStrings);
728x90