1 minute read

디자인패턴7- 전략 패턴 Strategy Pattern

  • 행위 패턴
  • “디자인 패턴의 꽃” “객체지향의 꽃”
  • 유사 행위들을 캡슐화하여 객체의 행위를 바꾸고 싶은 경우 직접 변경하는 것이 아닌, 전략만 변경하여 유연하게 확장
  • SOLID 설계 원칙 중 개방폐쇄원칙 OCP와 의존역전원칙 DIP를 따름

🌟 구성요소

  1. 전략 메서드( Method(); )를 가진 객체(Object1, Object2)
  2. 전략객체를 사용하는 컨텍스트(strategy)
  3. 전략객체를 생성해 컨텍스트에 주입하는 클라이언트(client)
    • 컨텍스트 : 실행할 코드에 제공할 환경 정보들을 모아놓은 객체

https://velog.io/@minidoo/자바스크립트-실행-컨텍스트란-1

https://github.com/hy6219/TIL-Today-I-Learned-/blob/main/Spring/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4/%ED%96%89%EC%9C%84%ED%8C%A8%ED%84%B4/%EC%A0%84%EB%9E%B5%ED%8C%A8%ED%84%B4/%EC%A0%84%EB%9E%B5%ED%8C%A8%ED%84%B4.png?raw=true

전략패턴은 서블릿을 작성할 때 느꼈던 생각을 되돌이켜볼 수 있는 개념인 것 같았다

바로 어떤 값이 변경될 때 서블릿을 작성할 때 관련 부분을 모두 수정해주어야 했는데, 전략패턴을 이용하게 되면, “전략”만 변경해주면 된다! 이러한 것이 가능한 이유는

인코딩과 관련되어서 빗대어 접근한다면

  • 어떤 하나의 개념이 있는데
  • a방식과 b방식의 리턴하는 방식만 다른 경우처럼 처리하는 방식이 다른 경우에는
  • 인터페이스를 구현하여 생성하면 해결을 할 수 있다!

라는 개념적 기반에 근거한다

이렇게

  • 인터페이스
  • 인터페이스를 구현한 클래스들

이 있다면 이 모임이 전략이 될 것이고

인터페이스의 메서드를 환경정보를 담고 있는 객체(위에서는 Encoder) 메서드 내부에서 호출하게 된다면

우리는 앞서 말했던 전략(인터페이스를 구현한 클래스들)만 수정하거나 확장시키면 된다!

먼저, 공통된 기능을 묶는 인터페이스인 EncodingStrategy를 설정해보자

  • 이 인터페이스는 문자열을 입력받아 인코딩처리하여 문자열로 반환해준다
package com.designPattern.action.strategy;

public interface EncodingStrategy {
    String encode(String text);//스트링을 받아서 인코딩해주는 메서드
}

그리고 이를 구현하여

  • 별도의 인코딩 처리 없이 반환해주는 NormalStrategy
  • Base64 방식으로 인코딩 처리 후 반환해주는 Base64Strategy

가 있다고 하면 각각은 아래와 같이 작성될 수 있다

package com.designPattern.action.strategy;

public class NormalStrategy implements EncodingStrategy{
    @Override
    public String encode(String text) {
        return text;
    }
}
package com.designPattern.action.strategy;

import java.util.Base64;

public class Base64Strategy implements EncodingStrategy{
    @Override
    public String encode(String text) {
        return Base64.getEncoder().encodeToString(text.getBytes());
    }
}

그리고 이 전략들을 변경해주기 위한 환경설정 객체(컨텍스트)로 Encoder 클래스를 작성하는데 이 클래스는

  • 전략 인터페이스인 EncodingStrategy를 필드로 갖는다
  • 전략인터페이스의 메서드를 내부적으로 호출하는 메서드를 갖는다
package com.designPattern.action.strategy;

public class Encoder {
    //Encoder는 상황에 따라 인코딩을 주입받을 것
    private EncodingStrategy encodingStrategy;

    public String getMessage(String message){
        return this.encodingStrategy.encode(message);
    }
    public void setEncodingStrategy(EncodingStrategy encodingStrategy) {
        this.encodingStrategy = encodingStrategy;
    }
}

이제 이러한 패턴이 어떻게 작동하는지 확인해보자

package com.designPattern.action.strategy;

import com.designPattern.generator.singleton.A;

public class StrategyMain {
    public static void main(String[] args){
        Encoder encoder=  new Encoder();

        //base64
        EncodingStrategy base64 = new Base64Strategy();

        //normal
        EncodingStrategy normal = new NormalStrategy()

        String msg = "Hello Java!";
        encoder.setEncodingStrategy(base64);
        String base64Res = encoder.getMessage(msg);

        encoder.setEncodingStrategy(normal);
        String normalRes = encoder.getMessage(msg);

        System.out.println("base 64: "+base64Res+", normal : "+normalRes);//base 64: SGVsbG8gSmF2YSE=, normal : Hello Java!

      }
}

위에서 확인해볼 수 있듯이, 인코딩 처리 방식이 달라진다고 해서, 클라이언트(Main)에서 별도의 번거로운 작업없이, 환경설정 객체를 이용하여 전략만 변경해주면 그에 맞는 행위를 실행하게 된다!

Updated: