Strategy

동일 계열의 알고리즘군을 정의하고, 각 알고리즘을 캡슐화하며, 이들을 상호교환이 가능하도록 만든다.

알고리즘을 사용하는 클라이언트와 상관없이 독립적으로 알고리즘을 다양하게 변경할 수 있게 합니다.

strategy-diagram

  • Strategy

    제공하는 모든 알고리즘에 대한 공통의 연산들을 인터페이스로 정의한다.

    Context 클래스는 ConcreteStrategy 클래스에 정의한 인터페이스를 통해 실제 알고리즘을 사용한다.

  • ConcreteStrategy

    Strategy 인터페이스를 실제 알고리즘으로 구현한다.

  • Context

    ConcreteStrategy 객체를 통해 구성된다.

    Strategy 서브클래스의 인스턴스를 가지고 있으며 구체화 한다.

    Strategy 객체가 자료에 접근해가는데 필요한 인터페이스를 정의한다.

Strategy 패턴 적용

  • Context

    class ResponseParser {
      constructor(private parser: ResponseParseStrategy) {}
    
      parse(response: IResponse) {
        return this.parser.parse(response);
      }
    }
    

    ConcreteStrategy를 이용하여 실제 알고리즘을 실행시킨다.

  • Strategy & ConcreteStrategy

    interface ResponseParseStrategy {
      parse(response: IResponse);
    }
    
    class GraphParser implements ResponseParseStrategy {
      parse(response: IResponse) {
        let parseResult = {};
    
        // 그래프 데이터 파싱 알고리즘
    
        return parseResult;
      }
    }
    
    class UserParser implements ResponseParseStrategy {
      parse(response: IResponse) {
        let parseResult = {};
    
        // 유저 데이터 파싱 알고리즘
    
        return parseResult;
      }
    }
    
  • 사용

    const graphParser = new ResponseParser(new GraphParser());
    const userParser = new ResponseParser(new UserParser());
    
    graphParser.parse(response);
    userParser.parse(response);
    

Contextsetter를 추가하여 strategy를 변경하기도 한다.

  • 예시

    class ResponseParser2 {
      private parser: ResponseParseStrategy;
      parse(response: IResponse) {
        return this.parser.parse(response);
      }
      setStrategy(parser: ResponseParseStrategy) {
        this.parser = parser;
      }
    }
    
    const responseParser = new ResponseParser2();
    
    responseParser.setStrategy(new GraphParser());
    responseParser.parse(response);
    
    responseParser.setStrategy(new UserParser());
    responseParser.parse(response);
    

장점

  • 행동이 조금씩만 다른 클래스들이 여러개 존재할 때 유용하게 사용된다.

  • 전략관련 로직들을 재사용할 수 있다.

  • Condition문을 Context로 이동하여 추상화할 수 있다.

단점

  • 사용자가 Strategy에 대해 알고있어야 한다.

    strategy를 어떻게 사용하는지 알아야 Context를 구성할 수 있다.

    Factory 패턴(Abstract Factory or Factory Method)을 적용을 고려해볼만 하다

  • 객체 수가 증가한다.

    각 로직을 Strategy로 분리하며 객체의 수가 증가한다.

Strategy 패턴은 조건이 많아지고 조건문에 대한 로직이 비슷한 부분도 있고 다른 부분도 있을 때 적용을 고려해볼만 한것 같다.

조건문의 분기가 3개 이상이 되면 함수가 길어지기 때문에 각 조건에 따른 로직을 고려하여 Strategy 패턴 적용은 충분히 고려해볼만 하다.

또한 패턴 적용을 고려하며 공통 로직, 개별 로직 분리를 고려하는 과정 자체가 더 나은 리팩토링 방법으로 이끌어줄 수도 있다.