#Strategy Pattern

 

 

1. 개념

 

전략 패턴(Strategy Pattern)이란 알고리즘 대체를 위해

동일한 목적을 지닌 알고리즘군을 인터페이스로 묶고

캡슐화하여 서로 대체가 가능하게 사용하는 것을 말한다.

 

예를 들어

종로에서 충무로를 가는 방법을 생각해보자

시간이 들더라도 걸어갈 수 있으며

택시를 타도 되고

버스나 지하철을 탈 수도 있다.

각각의 시간과 비용은 모두 다르지만

한 곳을 간다는 목적은 동일하다.

 

이처럼 비슷한 목적을 지닌 알고리즘을 묶어서

서로 상호교환이 가능하도록 만드는 패턴을

전략 패턴이라 한다.

 

 

2. Why? 왜 사용해야 할까?

 

구현된 알고리즘은 다르지만 동일한 목적을 지닌 클래스들이 존재할 때

전략 패턴을 사용하는 것이 좋다.

한 가지 알고리즘을 평소에 사용하더라도

참조하는 클래스의 변경이나 제거 등 여러가지 상황이 발생하거나

사용하는 시점에 따라서 알고리즘을 변경해야 하는 상황이 있을 수 있다.

이런 경우 언제든지 알고리즘을 쉽게 대체할 필요성이 있으며

전략 패턴을 사용하게 된다면

새로운 알고리즘을 추가하는 확장이 용이하기 때문이다.

 

 

3. 장단점

 

전략 패턴은 알고리즘의 변경 부분만을 따로 빼내어 구현한 것이므로

알고리즘마다 사용되는 코드 중복을 방지할 수 있으며

알고리즘을 쉽게 대체할 수 있고

확장성이 용이하여 다양한 알고리즘을 쉽게 추가할 수도 있다.

클라이언트와 독립적이기 때문에 알고리즘 변경에 대해서도 강하다.

 

그러나

알고리즘이 늘어날수록 객체도 무한정 늘어나며

클라이언트가 사용할 객체를 직접 결정해야 하기 때문에

많은 알고리즘에 대한 성능과 효율을 알고 있어야 하고

서로간의 차이를 알아야 하는데

직접 만든 것이 아니라면 부담스러울 수 있다.

 

 

4. 추가내용

 

앞서 템플릿 메소드 패턴에서 언급했듯이

보통 전략 패턴은 템플릿 메소드 패턴과 비교가 된다.

전략 패턴은 템플릿 메소드 패턴과 구성은 동일하지만 사용목적이 다르다고 볼 수 있다.

템플릿 메소드 패턴 공통된 메소드를 통해서 코드의 중복없이 사용하는 것이고

전략 패턴 상황에 맞는 필요한 전략을 선택하기 위해 사용하는 패턴이다.

 

그리고

객체의 행위를 유연하게 확장하고 구조가 데코레이터 패턴과 유사하지만

전략 패턴코드 내부의 알고리즘을 변화시키고

데코레이터 패턴코드 외부의 리턴 값을 변화시킨다는 점에서 차이가 있다.

 

 

5. 클래스 다이어그램

 

 

6. 예제 코드

 

포켓몬을 잡는 코드를 보며 전략 패턴에 대해서 알아보자

당신은 포켓몬 게임을 시작하며 스타팅 포켓몬으로 치코리타를 받았다.

당신에겐 절실히 다른 포켓몬이 필요하여 잠만보를 잡으려 한다.

당신에겐 몬스터볼, 하이퍼볼, 마스터볼이 있다.

세 개의 몬스터볼을 전략 1,2,3으로 구현하였고 몬스터볼 인터페이스로 묶어봤다.

public interface MonsterBall {
	
	public int throwBall();

}

public class Strategy1 implements MonsterBall{

	@Override
	public int throwBall() {
		System.out.println("몬스터 볼을 던진다.(확률:20%, 가격: 천원)");
		return 1;
	}
}

public class Strategy2 implements MonsterBall{

	@Override
	public int throwBall() {
		System.out.println("하이퍼볼을 던진다.(확률:50%, 가격: 삼천원)");
		return 4;
	}
}

public class Strategy3 implements MonsterBall{

	@Override
	public int throwBall() {
		System.out.println("마스터볼을 던진다.(확률:100%, 가격: 백만원)");
		return 9;
	}
}

 

Player1 캐릭터는 포켓몬을 잡기 위해 몬스터볼을 던질 수 있게 만들었고

전략을 파라미터로 받는다.

public class Player1 {
	
	public int getPokemon(MonsterBall monsterBall) {
		
		return monsterBall.throwBall();
		
	}
}

 

당신은 나중을 위해 하이퍼볼과 마스터볼을 아껴놓기로 하고

일반 몬스터볼(전략1)을 던져보기로 결정했다.

import java.util.Random;

public class PokemonGame {

	public static void main(String[] args) {
		
		Player1 player1 = new Player1();
		
		System.out.println("야생의 잠만보가 출현했습니다.");
		Random random = new Random();
		
		int ran = random.nextInt(10);
		int prob = player1.getPokemon(new Strategy1());
		
		if(ran <= prob) {
			System.out.println("잠만보를 잡았습니다!");
		} else {
			System.out.println("아쉽게 놓쳤다, 잠만보가 도망쳤다.");
		}

	}
}

 

결과는 다음과 같다.

 

 

7. 참고

 

https://rearrangingall.blogspot.com/2017/01/01-strategy-pattern.html

https://niceman.tistory.com/133

https://kimsunzun.tistory.com/entry/Strategy%EC%A0%84%EB%9E%B5-%ED%8C%A8%ED%84%B4

GoF의 디자인 패턴

 

 

Made by 꿩

'스터디 > GoF의 디자인패턴' 카테고리의 다른 글

Chain of Responsibility  (0) 2019.05.06
Template Method Pattern  (0) 2019.04.30
Decorator Pattern  (0) 2019.04.28
Factory Method Pattern  (0) 2019.04.23

+ Recent posts