Java

전략 패턴

ryeonng 2024. 9. 27. 10:44

사전 기반 지식

  • 인터페이스와 다형성 : 인터페이스를 사용하여 서로 다른 구현체를 동일하게 처리하는 개념을 이해해야 한다.
  • 메서드 오버라이딩 : 상위 클래스나 인터페이스에서 정의된 메서드를 하위 클래스에서 재정의하여 사용하는 방법을 알고 있어야 한다.

전략 패턴(Strategy Pattern)

동작 방식을 캡슐화하여, 동적으로 전략을 변경할 수 있도록 하는 디자인 패턴.

특정 기능을 수행할 여러 방법이 있을 때, 그 방법들을 전략(클래스)으로 정의하고, 필요에 따라 적절한 전략을 선택하여 사용할 수 있다.

package strategy;

import java.util.Base64;



public class StrategyTest {
    public static void main(String[] args) {
        
        // 클라이언트 측 코드
        String message = "password 123";

        // 1. 텍스트를 인코딩하는 클래스를 메모리에 올린다.
        Encoder encoder = new Encoder();

        // 전략 클래스 미리 생성해보기
        NormalStrategy normalStrategy = new NormalStrategy();
        Base64Strategy base64Strategy = new Base64Strategy();
        AppendStrategy appendStrategy = new AppendStrategy();
        
        
       
        // 서버 측에서 요청하는 전략을 선택해서 설정
        encoder.setEncodingStrategy(base64Strategy);

        // 기능 호출하기
        String outputMessage1 = encoder.getMessage(message); // "password 123" 이 인코딩되어 return 
        System.out.println(outputMessage1);

        // 전략 변경하기
        encoder.setEncodingStrategy(appendStrategy);

        // 두 번째 기능 호출하기
        String outputMessage2 = encoder.getMessage(message);
        System.out.println(outputMessage2);

        // 전략 변경하기
        encoder.setEncodingStrategy(normalStrategy);

        // 세 번째 기능 호출하기
        String outputMessage3 = encoder.getMessage(message);
        System.out.println(outputMessage3);


    } // end of main
}

// 인코딩 전략 인터페이스
interface EncodingStrategy {
    String encode(String text);
}

// 일반 텍스트를 보내는 전략 클래스 생성
class NormalStrategy implements EncodingStrategy {
    @Override
    public String encode(String text) {
        return text;
    }
}

// Base64 인코딩 전략
class Base64Strategy implements EncodingStrategy {
    @Override
    public String encode(String text) {
        return Base64.getEncoder().encodeToString(text.getBytes());
    }
}

// 특정 문자열을 추가하는 인코딩 전략
class AppendStrategy implements EncodingStrategy {
    @Override
    public String encode(String text) {
        return text + ":" + "not base64";
    }
}

// HTML 인코딩 전략을 만들어 보자
 // http://localhost:8080/name=%22%EC%9E%90%EB%91%90%22
class HtmlStrategy implements EncodingStrategy {
    @Override
    public String encode(String text) {
        return text;
    }
}

// * 핵심 - 클라이언트 클래스
class Encoder {

    private EncodingStrategy encodingStrategy;

    // 2. 전략에 따라 메세지를 인코딩하여 반환
    public String getMessage(String message) {
        return this.encodingStrategy.encode(message);
    }

    // 3. 전략을 따라서 동적으로 전략을 선택할 수 있는 기능
    public void setEncodingStrategy(EncodingStrategy encodingStrategy) {
        this.encodingStrategy = encodingStrategy;
    }
}

 

활용 사례

전략 패턴은 행위를 동적으로 변경해야 할 때 유용하게 사용된다. 특히, 클라이언트 코드에서 조건문을 사용하지 않고도 다양한 동작을 실행할 수 있는 구조를 만들 때 매우 유용하다.

  1. 암호화/인코딩 알고리즘 선택 : 다양한 암호화/인코딩 방식 중에서 동적으로 선택해야 할 경우, 전략 패턴을 통해 동작을 변경할 수 있다.
  2. 게임 개발 : 게임 캐릭터의 행동(공격, 방어 등)을 다르게 설정할 때 전략 패턴을 사용하여 동적인 행동 변경을 구현할 수 있다.
  3. 결제 처리 시스템 : 결제 방식(신용카드, 카카오 결제, 계좌이체 등)을 동적으로 선택할 수 있는 시스템에서 각 결제 방식을 전략으로 정의할 수 있다.

요약

  • 전략 패턴은 DIP(의존 역전 원칙)을 완벽히 준수하는 패턴이다.
  • 상위 모듈(클라이언트)은 구체적인 구현에 의존하지 않고, 추상화된 인터페이스에 의존하기 때문에, 시스템이 더 유연하고 확장 가능해진다.
  • 새로운 전략을 추가하거나 변경하더라도 클라이언트 코드는 수정하지 않고 전략(구현체)을 동적으로 설정하여 다양한 동작을 수행할 수 있다.

'Java' 카테고리의 다른 글

래퍼 클래스  (0) 2024.10.01
GET 방식과 URL 주소 설계  (0) 2024.09.27
싱글 톤 패턴  (0) 2024.09.26
콜백 메서드 만들어 보기  (0) 2024.09.26
어댑터 패턴  (2) 2024.09.26