안녕하세요. 회사와 함께 성장하고 싶은 KOSE입니다.

이번 포스팅은 디자인 패턴의 전략 패턴 (Strategy Patten)에 대해서 정리하는 시간을 가지려고 합니다.

 

1. 전략 패턴(Strategy Pattern)

객체들이 할 수 있는 행위 각각에 대해 전략 클래스를 생성하고 유사한 행위들을 캡슐화하는 인터페이스를 정의하며, 

객체의 행위를 동적으로 바꾸고 싶을 경우 직접 행위를 수정하지 않고 전략을 바꿔주기만 함으로써 행위를 유연하게 확장하는 

방법을 의미합니다. 

전략패턴의 의도는 알고리즘 제품군을 정의하고 각각을 캡슐화하여 상호 교환 가능하게 만들어, 전략을 사용하면 알고리즘을 사용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있습니다.

https://ko.wikipedia.org/wiki/%EC%A0%84%EB%9E%B5_%ED%8C%A8%ED%84%B4

 

https://ko.wikipedia.org/wiki/%EC%A0%84%EB%9E%B5_%ED%8C%A8%ED%84%B4

Context라는 행위가 이루어질 때, 해당 행위를 하는 객체는 각각 조금씩 다른 전략을 사용해야 할 수 있습니다.

만약, 행위가 전략에 의존적이게 되어, 다른 객체가 생성이 될 때, 전략 자체를 수정해야 하는 상황이 생긴다면 개방-폐쇄 원칙(OCP)에 위배되는 상황이 생깁니다.

 

따라서, 전략 패턴을 사용하면, ContextStrategy 인터페이스에 행위에 대한 전략을 위임합니다. 이는 곧 확장에 유리하고, 유연한 설계가 가능해집니다. Strategy 인터페이스를 구현한 구현체를 전략으로 사용하게 된다면, 수많은 행위가 생겨나서 전략의 확장이 필요하더라도 구조를 바꾸지 않고 확장 설계가 가능해집니다.

 

>> OCP란?

소프트웨어 개발 작업에 이용된 많은 모듈 중에 하나의 수정을 가할 때, 그 모듈을 이용하는 다른 모듈을 줄줄이 고쳐야 한다면, 프로그램을 수정하기가 어렵습니다. 개방-폐쇄 원칙은 시스템의 구조를 올바르게 재조직하여 나중에 이와 같은 유형이 변경이 되어 더 이상의 수정을 유발하지 않도록 하는 것입니다.

 

OCP의 특징 

- 확장에 대해 열려있다. (모듈의 동작을 확장할 수 있다.)

- 수정에 대해 닫혀있다. (모듈의 소스 코드나 바이너리 코드를 수정하지 않아도 모듈의 기능을 확장하거나 변경할 수 있다)

 

 

2. 코드로 확인하기

@AllArgsConstructor
public class ContextV1 {

    private Strategy strategy;

    // execute를 strategy에 위임
    public void execute() {
        strategy.execute();
    }
}
public interface Strategy {

    // 전략 패턴에 사용할 인터페이스의 메서드
    void execute();
}
public class StrategyLogic1 implements Strategy {

    // 전략 첫 번째
    @Override
    public void execute() {
        System.out.println("전략 1번을 사용합니다.");
    }
}
public class StrategyLogic2 implements Strategy {

    // 전략 두 번째
    @Override
    public void execute() {
        System.out.println("전략 2번을 사용합니다.");
    }
}
    /**
     * 전략 패턴 사용
     */
    @Test
    public void strategyV1() throws Exception {
        //given
        StrategyLogic1 strategyLogic1 = new StrategyLogic1();
        
        // execute 행위에 대한 전략을 선택 하기 위해 생성자 생성
        ContextV1 contextV1 = new ContextV1(strategyLogic1);
        
        // 행위 실행
        contextV1.execute();
    }

 

+ 전략 패턴을 사용할 때, 필드로 의존관계 주입을 통해 전략을 먼저 설정한 후 실행하는 방법도 있고, 전략 패턴을 파라미터로 전달 받아서 처리하는 방법도 있습니다. 

 

3. 정리

전략 패턴은 특정 작업을 다양한 방식으로 수정하는 클래스를 선택한 후, 모든 알고리즘을 전략들이라는 별도의 클래스로 추출할 것을 제안합니다. 

콘텍스트(Context)라는 콘텍스트는 작업을 자체적으로 실행하는 대신 연결된 전략 객체에 위임합니다.

 

따라서, 

콘텍스트는, 사용할 전략을 전략 객체에 위임 ->위임받은 전략 객체가 해당 행위 실행하는 방식으로 활용할 수 있습니다.

 

감사합니다.!

 

참조:

스프링 핵심 고급 원리 - 영한님 강의 https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B3%A0%EA%B8%89%ED%8E%B8/dashboard 

+ Recent posts