반응형

전략 패턴은, 개체들을 인터페이스로 일반화하여 서로 종속적이지 않고 독립적으로 유연하게 만드는 패턴이다.


중요! 전략 패턴은 중요한 패턴이기 때문에 반드시 이해하고 넘어가야한다.



전략 패턴은 유사한 함수나 객체로 만들어 질 가능성이 있는 개체들을 인터페이스로 추상화 시킨다.


유사한 개체들을 모아 인터페이스 시키는 방법은 전략 패턴 말고도 여럿 존재한다.


하지만 다른 방법을 썼음에도 불구하고 코드가 복잡해지는 경우가 있다.



예를 들어 설명하자면, 


콜로세움에서 마상 전투를 한다.


마상 전투에 참가하는 종족들을 BattleOfTheHorse 클래스를 상속한다.


BattleOfTheHorse 클래스는 타기과 무기 장착 함수를 갖는다.


마상 전투에 참가하는 종족이 인간, 오크, 바이킹 세 종족이 있다.


마상 전투는 기본적으로 말과 창을 사용하기 때문에 Ride와 Equip를 상속하여 사용한다.



하지만 종족간의 전투이기 때문에 룰의 변동이 필요했다.


오크 종족이 너무 무겁기 때문에 말을 탈 수 없었다.


그래서 소를 허용하도록 했다.


때문에 Ride 함수를 나누어야 하는데, 나누는 방법은 여러가지가 있다.


1. Ride 함수를 인터페이스로 분리시켜, 각 각의 Sub Class에서 재정의 하는 방법

2. 소를 타는 종족과 말을 타는 종족으로 나누어 상속받는 방법

3. 부모 클래스에 소와 말의 Ride 함수를 각 각 만드는 방법

4. 전략 패턴!


1. Ride 함수를 인터페이스로 분리시켜, 각 각의 Sub Class에서 재정의 하는 방법

1번 방법을 사용하여 인터페이스를 분리시키겠다.



해결 되었다. 끝


이 방법은 Ride 인터페이스를 상속받는 각 각의 개체 내에서 Ride에 해당하는 부분을 구현해 주어야 한다.


때문에 상속받는 개체가 수백, 수천개 이상이 된다면? 답이 없다.


적은 수의 개체만이 필요하다면 이 방법으로 해결하는 것이 좋을 수도 있다.


전략 패턴은 많은 수의 개체를 대상으로 효율적이기 때문에 1번은 원하는 해결 방법은 아니었다.



2. 소를 타는 종족과 말을 타는 종족으로 나누어 상속받는 방법

2번 방법은 종족을 나누는 것이다.


인간과 바이킹은 말, 오크는 소를 타는 종족으로 나누어 보겠다.



해결 되었네..? 끝?


하나의 방법이 될 수 있지만, 만약 종족 캐릭터의 성격까지 반영되어 말을 못타는 종족이 있다면? (억지..)


모두가 같은 특성을 가지고 있지 않기 때문에 원하는 정답이라 할 수 없다.


어떤 개체에서든 유연할 수 있도록 만들어야한다.



3. 부모 클래스에 소와 말의 Ride 함수를 각 각 만드는 방법

3번 방법은 부모 클래스에서 추가하는 방법이다.


UML도 필요없다.


CowRide(), HorseRide() 함수를 추가하면 된다.


하지만 이 방법은 모든 서브 클래스들이 소와 말 모두를 탈 수 있도록 되기 때문에 해결 되었다고 볼 수 없다.



4. 전략 패턴!

이제 우리가 원하는 전략패턴!


때문에 분리될 가능성이 있는 함수를 모두 인터페이스화 시켜 독립적으로 나누어 주는 역할을 하는 것이 전략 패턴이다.



위와 같이 IRide로 함수를 분리시키고, Ride 함수 내에서 IRide 인터페이스 내의 Ride 함수를 실행시키면 된다.


서브 클래스를 생성할 때에 원하는 IRide 클래스로 초기화 시켜주면 되는 것이다.


만약 소와 말이 아닌 돼지가 추가된다 하더라도, IRide의 구현 개체만 추가해주면 되기 때문에 독립적이고 유연한 패턴이 된다.


위에서 함수를 분리시키는 방법들과, 전략 패턴과의 차이에 대해 확인해 보았다.


전략 패턴은 디자인 패턴 중에서도 가장 많이 사용되는 패턴이고 또 가장 중요한 패턴이다.


확실히 자신의 것으로 만들고 넘어가는 것을 추천한다.



아래의 예제는 Ride 함수뿐 아니라 Equip 함수까지 패턴화 시킨 예제이다.


다음 코드처럼 분리시킬 필요가 없는 함수는 굳이 전략 패턴으로 사용하지 않아도 된다.


이해를 돕기 위하여 두 함수 모두 패턴화 시킨 것이다.



반응형

+ Recent posts