자바

디자인 패턴 7. 전략 패턴 (Strategy Pattern)

호놀롤루 2022. 3. 12. 20:23

1. 개요

전략 패턴은 객체지향의 꽃이라 할 수 있다.

유사한 행위들을 캡슐화하여, 객체의 행위를 바꾸고 싶은 경우, 직접 변경이 아닌, 전략만 변경하여 유연하게

확장하는 SOLID중 개방폐쇄 원칙(OCP), 의존역전 원칙(DIP)을 따르는 패턴이다.

 

3가지 필수 요소가 있다.

1. 전략 메소드를 가진 전략 객체 (인코딩의 경우 "그냥", "Base64", "사용자 설정" 등)

2. 전략 객체를 사용하는 컨텍스트 (인코딩의 경우 "Encoder")

3. 전략 객체를 생성해 컨텍스트에 주입하는 클라이언트 (Main)

 

인코딩의 경우 Base64, 32, 해시코드, 암호화 등 여러가지 전략이 있다.

인코더 객체 자체는 변하지 않고 전략 주입에 따라 결과가 달라지게 하는 것이다.

 

이런 디자인 패턴을 알고 있으면 좀 더 유연하고 확장성 좋은 소프트웨어를 개발할 수 있다.

 

 

2. 코드

package com.company.design.strategy;

public interface EncodingStrategy {
    String encode(String text);
}

 

package com.company.design.strategy;

public class NormalStrategy implements EncodingStrategy {
    @Override
    public String encode(String text) {
        return text;
    }
}

encode() 하면 텍스트를 원본으로 반환한다.

 

package com.company.design.strategy;

import java.util.Base64;

public class Base64Strategy implements EncodingStrategy {
    @Override
    public String encode(String text) {
        return Base64.getEncoder().encodeToString(text.getBytes()); // 자바 자체에서 지원
    }
}

encode() 하면 텍스트를 Base64로 인코딩해서 반환한다.

 

package com.company.design.strategy;

public class AppendStrategy implements EncodingStrategy {

    @Override
    public String encode(String text) {
        return "ABCD"+text;
    }
}

encode() 하면 원본 텍스트 앞에 "ABCD"를 붙여 반환한다.

 

package com.company.design.strategy;

public class Encoder {

    private EncodingStrategy encodingStrategy;

    public String getMessage(String message) {
        return this.encodingStrategy.encode(message);
    }

    public void setEncodingStrategy(EncodingStrategy encodingStrategy) {
        this.encodingStrategy = encodingStrategy;
    }

}

멤버 변수로 인터페이스를 가지고, 이게 다형성의 역할을 한다.

setEncodingStrategy 메소드로 멤버 변수인 인터페이스에 원하는 전략을 집어넣을 수 있다.

그리고 getEncodingStrategy() 메소드로 현재 멤버변수인 전략에 파라미터를 집어넣어 반환한다.

 

package com.company.design.strategy;

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

        // base64
        EncodingStrategy base64 = new Base64Strategy();

        // normal
        EncodingStrategy normal = new NormalStrategy();

        String message = "Hello java";
        encoder.setEncodingStrategy(base64);
        String base64Result = encoder.getMessage(message);
        System.out.println(base64Result);

        encoder.setEncodingStrategy(normal);
        String normalResult = encoder.getMessage(message);
        System.out.println(normalResult);


        encoder.setEncodingStrategy(new AppendStrategy());
        String appendResult = encoder.getMessage(message);
        System.out.println(appendResult);

    }
}

결과

SGVsbG8gamF2YQ==
Hello java
ABCDHello java

 

우선 Encoder를 생성하고, base64, normal 전략을 생성한다.

message에 "Hello java"를 집어넣고, encoder의 전략을 base64로 세팅한다.

그리고 base64Result 변수에 message를 인코딩하면 Base64로 인코딩 된 문자열이 들어간다.

sout으로 출력하면서 결과가 나온다.

 

그 다음은 Encoder의 전략에 normal을 집어넣고 같은 동작을 반복한다.

 

마지막으로 Encoder에 임의로 만든 Append 전략을 집어넣는다. (굳이 계속 쓸 게 아니라서 인스턴스 생성해서 넣음)

그리고 그걸 Result에 넣어서 출력하는 과정이다.

 

Encoder 클래스를 건드리지 않고 전략을 바꾸는 것 만으로 다른 결과를 출력하는 전략 패턴을 알아보았다.