Strategy pattern


스트래티지 패턴(Strategy pattern)

스트래티지 패턴(Strategy pattern) 에서는 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다.
스트래티지를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할수있다.
즉, 쉽게 말하면 클래스안에서 행동을 하는 것들을 멤버함수로 설정하지말구, 행동하는것을 따로 클래스로 만드는 방법.
(행동클래스는 상속해서 구현된다.)

 

Strategy Pattern 적용 전

 

만약 이런 문제가 있다고 쳐보자.

이 세상의 오리들을 클래스화 한다고 하자.

진짜 오리처럼 보이게 하기 위해 오리 클래스들에 다음과 같이 '수영하다'라는 행위를 구현해 놓았다.

 

class MalladrDuck {

public: 
void swim() { printf("MallardDuck is swimming."); } }   class RubberDuck { public:
void swim() { printf("RubberDuck is swimming."); } }


그런데 문제가 발생했다!!!

지금은 오리 클래스가 단 2개지만

앞으로 만드는 모든 오리 클래스들은 '날다'라는 행위와 '울다'라는 행위를 꼭 하도록 구현하게 하고 싶으면 어떻게 할까?

 

 

해결방법

1. 앞으로 구현하는 모든 오리 클래스에서 fly(), queak()라는 메소드를 직접 구현하도록 한다.

2. fly(), queak() 라는 추상 메소드를 포함한 Duck라는 부모 클래스를 만들어 앞으로 만드는 모든 오리 클래스들은

이 Duck 클래스를 상속받아 fly(), queak()라는 메소드를 꼭 오버라이딩하게 만든다.

 

얼핏 보기에도 1번은 좀 생각이 없어보이고...

2번이 답인거 같긴한다. 하지만 뭔가 뒤끝이 구린 느낌이다.

 

class Duck {
public:

       void swin() {
             printf(" 오리 swimming.");
       }
       vitual void fly() = 0;
       vitual void queak() = 0;

}
 
 
class SuperDuck : public Duck {
public:
void fly() { printf("슈퍼오리 flying"); }   void queak() { printf("슈퍼오리 queaking"); } }

 

 

왜 2번 해결방법이 비효율적인지 생각해보자.

 

만약 날지 않는 오리를 만들고 싶을 땐 어떻게 할 것인가?

간단하게 Duck 클래스를 상속 안받고 직접 오리클래스를 만들면 될거 같다고 생각하겠지만

오리들의 공통 행동인 swim()을 부모 클래스 Duck에 구현해놓았다.
(이것은 결국 Duck를 꼭 상속 받아야 한다는 의미!!)


결국 울며 겨자먹기 식으로 Duck 클래스를 상속 받아서 
날지 못하고 울지 못하는 오리는 fly(), queak() 메소드에 내용이 텅빈 메소드로 오버라이드 해야 한다.

이것은 Duck을 상속 받는 모든 오리들은 좋든 싫든 fly(), queak() 메소드를 꼭 오버라이드 해야 한다는 의미...

해결한 것 같긴한데 뭔가 찜찜하다. 뭔가 오리의 행동을 유연하게 확장할 수 있는 방법이 없을까?
====> 

이 때 필요한게 바로 Strategy Pattern 이다. 


 

--------------------------------------------------------------------------------------------------------------

 

Strategy Pattern 적용 후

 

그럼 위 문제를 어떻게 해결하면 좋을까?

발상을 전환해서 fly()나 queak() 같은 중요 행동 메소드(알고리즘)들을 클래스화 시키는 것이다.

그래서 오리 클래스들은 모두 공통 메소드들을 호출하도록 하고 공통 메소드들은 알고리즘 클래스들을 사용하는 것이다.

말로 설명하면 복잡할 수 있으나 소스코드를 보면 간단하다.

 

 
 

Strategy Pattern을 쓸 경우 장점은 뭘까?

 

1. 알고리즘을 캡슐화 시켰기 때문에 알고리즘 확장이 용이하다.

 위의 예제 코드를 보면 행동을 추가하려면 FlyBehavior의 자식클래스만 구현해주면 되기 때문

 

2. 프로그램이 실행 중에 알고리즘을 셋팅할 수 있다!!!!

 역시 위의 예제 코드를 살펴보면 main메소드에서 setFlyBehavior()라는 메소드를 통해 행동 객체를 셋팅하는 것을 볼 수 있다.  이것은 즉, 프로그램 실행 중에 알고리즘 객체를 생성하여 setter 메소드를 통해 런타임 시 셋팅하여 알고리즘을 실행시키고 있다는 것을 의미한다.

즉 객체지향을 고려한 재사용성과 확장성을 고려하여 적절히 Strategy Pattern을 적용시키면 중복코드를 상당히 줄일 수 있을 것이다.

 

 

 

[글,사진출처: Head First Design Patterns ]
[참고:http://blog.naver.com/crazybnn/30105172290]
[소스: 직접짬 ]


 

참고 공부하면서 패턴을 정리해봤다.
물론 소스는 내가 짠소스이다!! 
소스를 첨부함


 

이 글을 공유하기

댓글

Designed by JB FACTORY