ES6/Strategy 패턴

Strategy 패턴

디지털노마드-건물주 2024. 8. 29. 11:45
728x90

// 실행 Class 정의
class Runsea {
    run() {
        console.log("바다로 가자");
    }
}

class Runmount {
    run() {
        console.log("산으로 가자");
    }
}

// Commane Module
class Command {
    constructor(obj) {
        this.obj = obj;
    }
    run() {
        this.obj.run();
    }
}

new Command(new Runsea()).run(); // Runsea class 실행
new Command(new Runmount()).run(); // Runsea class 실행

// Strategy 모듈
// setStrategy(strst) 에 모듈 할당
// 할당후 실행
class StrategyRunner {
    constructor() {}
    setStrategy(strst) {
        this.strategy = strst;
    }
    run() {
        this.strategy.run();
    }
}

const stmodule = new StrategyRunner();

stmodule.setStrategy(new Runsea());
stmodule.run();

stmodule.setStrategy(new Runmount());
stmodule.run();

// JavaScript에서 "Strategy Pattern"(전략 패턴)은 객체 지향 디자인 패턴 중 하나로,
// 알고리즘을 각각의 클래스에 캡슐화하고, 이러한 알고리즘을 상호 교환할 수 있게 해줍니다.
// 이 패턴을 사용하면 특정 기능을 사용하는 클라이언트 코드가 그 기능의 구현 세부 사항에 의존하지 않으므로,
// 코드의 유연성과 확장성을 높일 수 있습니다.

// 1. Strategy 패턴의 기본 개념
//    1.1 컨텍스트(Context): 특정 전략을 사용하는 클래스입니다.
//        이 클래스는 클라이언트가 호출하는 메서드를 정의하고,
//        그 메서드에서 사용할 전략(알고리즘)을 실행합니다.
//    1.2 전략(Strategy): 인터페이스 또는 추상 클래스로, 다양한 알고리즘(또는 전략)을 정의합니다.
//        각 전략은 이 인터페이스를 구현하며, 알고리즘을 실제로 수행하는 역할을 합니다.
//    1.3 구체적인 전략(Concrete Strategy): 전략 인터페이스를 구현하는 클래스들로,
//        각각의 구체적인 알고리즘을 정의합니다.
// 2. 예제
//    아래 예제는 계산기 애플리케이션에서 덧셈, 뺄셈, 곱셈, 나눗셈과 같은 다양한 연산을 전략 패턴으로
//    구현하는 방법을 보여줍니다.

// 전략 인터페이스
class Strategy {
    execute(a, b) {
        throw new Error("execute() 메서드는 구현되어야 합니다.");
    }
}

// 구체적인 전략 클래스들
class AddStrategy extends Strategy {
    execute(a, b) {
        return a + b;
    }
}

class SubtractStrategy extends Strategy {
    execute(a, b) {
        return a - b;
    }
}

class MultiplyStrategy extends Strategy {
    execute(a, b) {
        return a * b;
    }
}

class DivideStrategy extends Strategy {
    execute(a, b) {
        return a / b;
    }
}

// 컨텍스트 클래스
class Calculator {
    constructor(strategy) {
        this.strategy = strategy;
    }

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

    calculate(a, b) {
        return this.strategy.execute(a, b);
    }
}

// 사용 예제
const calculator = new Calculator(new AddStrategy());
console.log(calculator.calculate(10, 5)); // 출력: 15

calculator.setStrategy(new SubtractStrategy());
console.log(calculator.calculate(10, 5)); // 출력: 5

calculator.setStrategy(new MultiplyStrategy());
console.log(calculator.calculate(10, 5)); // 출력: 50

calculator.setStrategy(new DivideStrategy());
console.log(calculator.calculate(10, 5)); // 출력: 2

// 코드 설명
// 1. Strategy 인터페이스:
//    Strategy 클래스는 기본적인 인터페이스(또는 추상 클래스)로, execute 메서드를 정의하고 있습니다.
//    이 메서드는 구체적인 전략 클래스에서 구현해야 합니다.
// 2. 구체적인 전략 클래스들:
//    AddStrategy, SubtractStrategy, MultiplyStrategy, DivideStrategy는 Strategy 클래스를 상속받아
//    각자 execute 메서드를 구현합니다. 각 클래스는 a와 b 두 숫자를 받아 특정 연산을 수행합니다.
// 3. Calculator (Context):
//    Calculator 클래스는 전략을 설정하고, calculate 메서드를 통해 설정된 전략을 실행합니다.
//    setStrategy 메서드를 통해 실행할 전략을 동적으로 변경할 수 있습니다.
// 4. 사용 예제:
//    Calculator 객체를 생성할 때 초기 전략(덧셈 전략)을 설정하고, 그 후 전략을 변경하며 다양한 계산을 수행합니다.

// Strategy 패턴의 장점
// 1. 유연성: 실행 중에 전략을 교체할 수 있어, 코드의 유연성이 높아집니다.
// 2. 코드 재사용: 서로 다른 전략을 별도로 구현하여 재사용할 수 있습니다.
// 3. 유지보수성: 알고리즘이 변경되거나 추가될 때, 기존 코드를 수정하지 않고 새로운 전략을 추가할 수 있습니다.
//    이 패턴은 상황에 따라 다양한 알고리즘을 사용해야 하는 경우에 매우 유용합니다. 예를 들어, 다른 필터링 방법,
//    검색 알고리즘, 정렬 방법 등을 필요로 하는 애플리케이션에서 사용될 수 있습니다.
728x90