책책책/토비의 스프링 3.1

[Spring] 전략패턴(Strategy Pattern)

Deveun 2021. 7. 31. 03:50

토비의 스프링 3장: 템플릿

전략패턴(Strategy Pattern) 이란

분리와 재사용을 위한 디자인 패턴

 

 

간단한 예제로 숫자 5개를 입력받아 덧셈, 뺄셈 결과를 출력하는 코드이다.

빨간색 박스 부분을 제외하고는 메소드마다 동일한 코드가 반복되고 있다.

이런 메소드가 여럿 있을 때, 매번 이전 코드를 Copy&Paste하면서 변하는 부분의 코드만 수정하는 방식으로 구현한다면?

공통된 구조에 수정이 생길 경우에 메소드의 갯수만큼 코드를 수정해줘야 하는 비효율성이 발생한다.

 

이런 경우에 메소드에서 변하지 않는 부분(Context)과 변하는 부분(Strategy)을 분리하여 변하지 않는 부분은 재사용하고, 변하는 부분의 코드만 목적에 따라 주입시켜주는 것이 바로 전략패턴이라고 할 수 있다.

 

이는 일정한 구조의 Context를 가지고 동작하다가, 특정 확장 기능 부분을 Strategy 인터페이스를 통한 전략 클래스에 기능을 위임하는 것이다. 위의 예제로 전략패턴의 구조를 적용해보면 다음과 같이 나타내진다.

 

 

context메소드 분리 -> 전략을 주입받아 수행

위와 같이 전략패턴을 적용하므로써 코드가 훨씬 간결해졌다.

하지만, 덧셈 / 뺄셈뿐만 아니라 새로운 method들이 더 추가된다고 생각해보자. 그 때마다 새로운 Strategy 구현 클래스를 생성해야 한다는 단점이 있는데, 이는 Strategy 구현 클래스를 로컬 클래스 or 익명 내부 클래스로 변환하는 방법으로 개선될 수 있을 것이다.

 

 

[전체코드]

 

Caculator.java

public class Caculator {

    public void sum() throws IOException{

        Strategy strategy = new SumStrategy();
        contextWithStrategy(strategy);
    }

    public void subtract() throws IOException{

        Strategy strategy = new SubtractStrategy();
        contextWithStrategy(strategy);
    }

    public void contextWithStrategy(Strategy strategy) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        try {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");

            int[] num = new int[5];
            num[0] = Integer.parseInt(st.nextToken());
            for(int i=1; i<5; i++) {
                num[i] = Integer.parseInt(st.nextToken());
                strategy.operationStrategy(num, i);
            }
            System.out.println("result = " + num[0]);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("failed");
        }
    }
}

Strategy.java

public interface Strategy {
    public void operationStrategy(int[] num, int i);
}

SumStrategy.java

public class SumStrategy implements Strategy{
    @Override
    public void operationStrategy(int[] num, int i) {
        num[0] += num[i];
    }
}

SubstractStrategy.java

public class SubtractStrategy implements Strategy{
    @Override
    public void operationStrategy(int[] num, int i) {
        num[0] -= num[i];
    }
}

 

 

 

[참고서적] http://www.acornpub.co.kr/book/toby-spring3.1-vol1#spring3

 

토비의 스프링 3.1 Vol. 1 스프링의 이해와 원리

스프링의 핵심 프로그래밍 모델의 원리와 이에 적용된 다양한 디자인 패턴, 프로그래밍 기법의 이해를 돕는 책

www.acornpub.co.kr