해당 포스트는 "자바 객체지향 디자인 패턴", "JAVA 언어로 배우는 디자인 패턴 입문" 책의 내용을 요약한 것이다.



※ 스트래티지(Strategy, 전략) 패턴

: 여러 알고리즘을 하나의 추상적인 접근점(interface)을 만들어 접근점에서 서로 교환 가능하도록 하는 패턴으로 변화하는(교환 가능한) 부분을 캡슐화하고 해당 기능을 인터페이스에 위임한다.

 

- Strategy : 인터페이스나 추상 클래스로 외부에서 동일한 방식으로 알고리즘을 호출하는 방법을 명시한다.

- ConcreteStrategy : 스트래티지 패턴에서 명시한 알고리즘을 실제로 구현하는 클래스이다.

- Context : 스트래티지 패턴을 이용하는 역할을 수행한다. 필요에 따라 동적으로 구체적인 전략을 바꿀 수 있도록 setter 메서드를 제공한다.

 

ex) 아톰과 태권V로봇이 있다. 이 두 로봇은 공격 기능과 이동 기능이 있는 데 아톰은 공격할 때 주먹만 사용하지만 하늘을 날 수가 있고, 태권V는 미사일로 공격할 수 있지만 날아다니지 못하고 걷기만 할 수 있다. 아래는 아톰과 태권V 로봇을 설계할 때 사용하는 클래스 다이어그램이다.

위와 같이 설계한 이유는 아톰과 태권V는 둘다 공격(attck 메서드)와 이동(move 메서드) 기능이 있는 로봇의 한 종류이기 때문이다. 아톰과 태권V는 이동기능과 공격기능이 서로 다르기 때문에 Robot 클래스에서 attack과 move 메서드를 추상 메서드로 설정해 자식 클래스에서 각각 정의하면 된다.

 

 

- 문제점

 

1. 예를 들어 아톰이 날 수 없고 오직 걷게만 만들거나 태권V를 날게 만들고 싶다면 즉, 기존 로봇의 공격 또는 이동 방법을 수정하려면 어떤 변경 작업을 해야 하는가?

=> 기존의 기능을 변경해야 하기에 attck()과 move() 메서드의 코드 내용을 수정해야한다. 그러면 OCP에 위배된다. 또한 태권V의 기능은 그대로 두고 아톰만 날 수 없고 걷게 만든다면 태권V의 move() 메서드와 아톰의 move()메서드가 중복된다. 그러면 만약 걷는 방식에 문제가 생기거나 새로운 방식으로 수정하려면 모든 중복된 코드를 일일이 변경해야 한다는 단점이 생긴다.

 

2. 아톰과 태권V 외에 새로운 로봇을 만든다고 하고 해당 로봇이 태권V처럼 미사일을 발사하고 날아다닌다면?

=> 새로운 로봇의 move() 메서드는 아톰의 move() 메서드와 attack() 메서드는 태권V의 attck()메서드와 중복이 발생한다. 

 

 

- 해결책 : 무엇이 변화되었는지를 찾은 후에 이를 클래스로 캡슐화한다.

로봇 설계에서의 문제를 해결하려면 무엇이 변화되었는지 찾아야한다. 변화한 것을 찾은 후에 클래스로 캡슐화해야 한다. 위 예제에서 변화되고 문제를 발생시키는 요인은 이동 방식과 공격 방식의 변화다. 따라서 이를 캡슐화해 구체적인 공격방식과 이동방식을 은닉해야한다. 이를 위해 공격과 이동을 위한 각각의 인터페이스를 만들어야 한다.

 

위와 같이 MovingStrategy와 AttackStrategy 인터페이스를 만든 후 Robot 클래스에서 setter함수를 통해 공격 기능과 이동 기능을 의존했다. 따라서 이동 방식이나 공격 방식이 변화할 시 클래스 내 코드의 변경 없이 변경이 가능해 OCP를 만족하는 설계가 된다.

 

 

이처럼 스트래티지 패턴은 전략을 쉽게 바꿀 수 있도록 해주는 디자인 패턴으로 같은 문제를 해결하는 여러 알고리즘(방식)이 클래스별로 캡슐화되어 있고 이들이 필요할 때 교체할 수 있도록 함으로써 동일한 문제를 다른 알고리즘으로 해결할 수 있게 하는 디자인 패턴이다. 

 

일반적인 예로는 Excel에서 데이터를 원형 차트/영역 차트/ 막대차트 중 특정 차트로 표현하는 것, 게임에서 상황에 따라 전략을 선택하는 것 등이 있다. 

 

'자바 > 디자인패턴' 카테고리의 다른 글

상태(State) 패턴  (0) 2017.07.03
싱글턴(Singleton) 패턴  (0) 2017.07.03
디자인 패턴  (0) 2017.06.29
책임 연쇄/사슬 패턴  (0) 2017.06.08
생성자의 인자가 많을 시 빌더 패턴  (0) 2017.06.08

+ Recent posts