ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Strategy Pattern(전략 패턴)
    STUDY/디자인패턴 2025. 3. 3. 18:48

    전략 패턴이란?

    실행(런타임) 중에 알고리즘 전략을 선택하여 객체 동작을 실시간으로 바뀌도록 할 수 있게 하는 행동 디자인 패턴으로, 특정 작업을 다양한 방식으로 수행하는 클래스를 선택한 후 모든 알고리즘을 전략들(strategies)이라는 별도의 클래스들로 추출한다.

     

    구조

    • Context

    구상 전략 중 하나에 대한 참조를 유지하고 전략 인터페이스를 통해서만 이 객체와 통신한다. 알고리즘을 실행해야 할 때마다 연결된 전략 객체의 실행 메서드를 호출한다. 

     

    • Strategy

    콘텍스트가 전략을 실행하는 데 사용하는 메서드를 선언한 전략 인터페이스

     

    • ConcreteStrategies

    구상 전략은 콘텐스트가 사용하는 알고리즘의 다양한 변형들을 구현한다.

     

    • Client

    특정 전략 객체를 만들어 콘텍스트에 전달한다.

     

    예시

    Strategy

    public interface Strategy {
        int execute(int a, int b);
    }

     

    ConcreteStrategies

    public class ConcreteStrategyAdd implements Strategy {
       @Override
        public int execute(int a, int b) {
            return a + b
        }
    }
    
    class ConcreteStrategySubtract implements Strategy {
        @Override
        public int execute(int a, int b) {
            return a - b
        }
    }
    
    class ConcreteStrategyMultiply implements Strategy {
        @Override
        public int execute(int a, int b) {
            return a * b
        }
    }

     

    Context

    public class Context {
    	private Strategy strategy;
        
        public void setStrategy(Strategy strategy) {
        	this.strategy = strategy;
        }
        
        public void executeStrategy(int a, int b) {
        	return strategy.execute(a, b);
        }
    }

     

    Client

    public class ExampleApplication {
        public static void main(String[] args) {
            Context context = new Context();
            
            int a = 10;
            int b = 5;
            String action = "addition";
    
            if (action == addition) {
            	context.setStrategy(new ConcreteStrategyAdd())
            }
            
            if (action == subtraction) {
            	context.setStrategy(new ConcreteStrategySubtract())
            }
            
            if (action == multiplication) {
            	context.setStrategy(new ConcreteStrategyMultiply())
            }
    
            System.out.println(context.executeStrategy(a, b));
        }
            
    }

     

    적용

    1. 객체 내에서 한 알고리즘의 다양한 변형들을 사용하고 싶은 경우
    2. 런타임 중에 한 알고리즘에서 다른 알고리즘으로 전환하고 싶은 경우
    3. 일부 행동을 실행하는 방식에서만 차이가 있는 유사한 클래스들이 많은 경우
    4. 알고리즘의 다른 변형들 사이를 전환하는 거대한 조건문이 존재하는 경우

     

    장단점

    장점

    • 런타임에 한 객체 내부에서 사용되는 알고리즘들을 교환할 수 있다.
    • 알고리즘을 사용하는 코드에서 알고리즘의 세부 구현 정보들을 분리할 수 있다.
    • 상속을 합성으로 대체할 수 있다.
    • 개방/폐쇄 원칙. 콘텍스트를 변경하지 않고도 새로운 전략들을 도입할 수 있다.

     

    단점

    • 알고리즘이 몇 개밖에 되지 않고 거의 변하지 않는 경우 새로운 클래스들과 인터페이스들로 프로그램이 지나지게 복잡해질 수 있다.
    • 클라이언트들은 적절한 전략을 선택할 수 있도록 전략 간의 차이점들을 알고 있어야 한다.
    • 많은 프로그래밍 언어에서 익명 함수들의 집합 내에서 알고리즘의 다양한 버전들을 구현할 수 있는 함수형 지원이 있으며, 클래스들과 인터페이스들을 추가하여 코드의 부피를 늘리지 않으면서도 전략 객체를 사용했을 때와 똑같이 이러한 함수들을 사용할 수 있다.
Designed by Tistory.