같은 목적을 수행하는 알고리즘을 동적으로 바꾸어 가며 사용하는 패턴
문자를 잘라주는 알고리즘이 있는데 문자를 한번에 한문자씩, 한라인씩 한 문단씩 또는 동일 단어씩으로
잘라주는 비슷한 알고리즘이 알고리즘있고 이를 가변적인 상황에서 동적으로 어떻게 설계할 것인가
how?
1. 각 case 별로 해당 알고리즘을 불러준다 => 후에 추가하면 나중에 case 문을 건드려야 하고, 하드코딩 되어 있으니 무뭔가
각 케이스안에서 전 후에 작업을 추가 할 경우도 건드려야 한다 => 좋지 않음
2. 처음 클라이언트가 어떤 알고리즘을 설정할때는 case 문이 들어갈 순 있지만
실행시에는 단한줄로 case 없이 실행 시키려면
부모 Abstract Base class 를 두고 알고리즘별 서브 클래스를 둔다
부모 ABC 에는 virtual void execute()=0; 정도로 공통 인터페이스를 두면 된다
A::Action( Strategy_AbstractAction* p ){
p->Execute();
}
원래 본체 실행 구문에서 때어놓아 따로 구현 하는 것이 좋다
=> Strategy* 를 어느 클래스나 실행 함수내의 등에서 포함관계 시켜 놓는 것이 좋다
context 클래스내에 같이 구현해 버리면 동적으로 교체를 못한다, 또한 구현이 복잡해 진다
Strategy 패턴은 변하는 것과 변하지 않는 것을 구분하고 변하는 것들에 대해서 위처럼 정의 한다
캐릭터의 동작을 동적으로 바꾸려면 클라이언트에서 class 만 부모 포인터로 할당해주면 된다
C 에서도 어떤 정렬 알고리즘을 하나로 묶기 위해 함수포인터를 사용 할 수 있다
하지만 다른 사람이 볼때 처음에 분석시 애매할 수 있다
하지만 클래스의 경우 클래스 명이 있기에 구분이 명확하다
어떤 알고리즘을 클라이언트가 알 필요가 없을때
case 문으로 작성할 경우 인자들을 써야 하는 경우가 생기기 때문에 Strategy 패턴으로 사용 시 유용
실행구문을 간단하게 처리 할 수 있다
공통된 알고리즘으로 추출해서 ABC 에 놓을 수 있다
알고리즘도 보호할 수 있는데 실행 되는 것은 ABC 구조내에서 사용 함으로 클라이언트를 알 필요가 없다
그럼으로 함수를 protected: 로 선언 할 수 있다
근대 공통된 인터페이스 이므로 공통 수행 함수에 아규먼트가 틀리면, 이에 대한 오버헤드가 있을 수 있다
context 클래스와 Strategy 는 서로 데이터를 쉽고 효율적으로 전달 할 수 있어야 한다
멤버함수로 필요한 데이터를 덭져 주는 것은 그나마 결합도를 떨어뜨릴 수 있는데
context class 의 데이터가 필요해서 context* 를 알고리즘인 Strategy 에 포함 시켜 버리고
해당 알고리즘 자식 클래스가 이 포인터를 사용하게 되는 경우
자식클래스가 context 를 다 알아버리는 꼴이 됨으로 결합도가 올라감으로
왼만하면 멤버함수로 값을 던져 주는게 좋다
또는 ->Execute() 를 수행하면서 이 함수에 인자를 넘겨도 되긴하지만 상속받는 전체 함수에 동일한 인자를 써야 한다는 것과
나중에 수정이 생기면 이부분의 상속 함수 인자부분을 전체 건드려야 하는 상황이 발생 함으로 판단하에 사용할 것
template 으로 실행할 알고리즘의 클래스를 작성할 수 있다
그런데 이경우 먼저 하위 클래스를 고정해 버림으로 동적으로 알고리즘을 바꾸기는 힘들다
static(고정) 하게 되어버려 template 을 써도 괜찮은지 한번 생각해 봐야 한다
알고리즘의 경우 요소 개수에 따라 빠른 알고리즘이 다를때 Strategy 패턴을 사용 하면 효과적이다
'디자인패턴과방법론 > 디자인패턴' 카테고리의 다른 글
visitor 패턴 (0) | 2012.11.02 |
---|---|
Template Method 패턴 (0) | 2012.11.02 |
state 패턴 (0) | 2012.11.02 |
Observer 패턴 (0) | 2012.11.02 |
memento 패턴 (0) | 2012.11.02 |