오늘 제가 2시간동안 슬램덩크 요약본을 너무 재밋게 봤습니다.
농구 게임에 캐릭터
가 있습니다. 기본적으로 슛
이 있고, 드리블
이 있죠.
먼저 이런식으로 기본기능들을 가진 슛
과 드리블
은 행동
이라고 표현할 수 있습니다.
우리회사의 열정적인 기획팀장님의 요구사항이 추가되다 보면
1. 슛
에 레이업슛
의 로직이 살짝 수정
된다거나,
2. 슛
을 누르면레이업슛
만 했는데 이게슬램덩크 슛
으로 변경
될수도 있고,
3. 드리블
에 성큼성큼 드리블
같은 새로운 놈이 추가
될 수도 있습니다.
어떤객체(캐릭터)
의 어떤행동(슛 or 드리블)
을 쉽게 수정
하고 변경
할 수 있게 하는 패턴입니다.
기본적으로 이 농구게임에는 슛
과 드리블
이라는 기능이 들어가야 한다고 합니다.
그렇다면 슛
과 드리블
을 행동집합
으로 볼 수 있겠군요. 이 행동집합에는 같은 슛
이지만 여러 종류의 슛
으로 나뉘니까요.
각 슛
과 드리블
에는 3개씩 다른 행동
들이 있습니다. 캐릭터가 슛
을 하거나 드리블
을 할 때 동작하는 행동들이지요.
즉, 어떤 행동을 자유롭게 바꾸고자 할때 사용하면 좋다는 것입니다.
의식의 흐름대로 상속이나 단순 인터페이스를 사용해서 구현 할 수 있지만, 이건 나중에 시간이 되면 다루도록 하겠습니다.
각 행동들을 부모 클래스에 정의하지 않고, 클래스 집합으로 만들어서 분리함으로(인터페이스로 분리후 그 인터페이스를 구현하는 방식으로) 쉽게 행동변경
을 할 수 있습니다. 그래서 setShoot()
, setDribble()
같은 함수를 부모클래스에 정의해주었습니다.
// 메인 클래스
//이런식으로 말이죠.
BasketBall 강백호 = new 강백호();
강백호.shoot(); // 슬램덩크 슛
강백호.setShoot(new Point3Shoot());
강백호.shoot(); // 3점 슛
public class BasketBall{
ShootInterface shootInterface;
DribbleInterface dribbleInterface;
public function shoot(){
shootInterce.shoot();
}
public function dribble(){
dribbleInterface.dribble();
}
public function setShoot(ShootInterface si){
shootInterface = si;
}
public function setDribble(DribbleInterface di){
dribbleInterface = di;
}
}
// 인스턴스 클래스
public class 강백호 extends BasketBall{
__constructor(){
shootInterface = new SlamdunkShoot();
dribbleInterface = new Dribble();
}
}
실제 구현은 외부 클래스로 위임
해주었으므로, 이 행동들을 호출할 수 있는 함수를 선언해 주었습니다(shoot()
, dribble()
).// 메인 클래스
BasketBall 강백호 = new 강백호();
// 위 강백호 클래스에서
// shootInterface에 SlamdunkShoot(); 을 할당한 게 보입니다.
// SlamdunkShoot클래스의 shoot(); 함수에서 실제 구현을 맡고 있는거죠.
강백호.shoot(); // 슬램덩크 슛
public class 강백호 extends BasketBall{
__constructor{
shootInterface = new SlamdunkShoot();
dribbleInterface = new RunDribble();
}
}
public class 정대만 extends BasketBall{
__constructor{
shootInterface = new Point3Shoot();
dribbleInterface = new RunDribble();
}
}
public class 송태섭 extends BasketBall{
__constructor{
shootInterface = new LayupShoot();
dribbleInterfade = new RunDribble();
}
}
public class PlayBasketBall{
BasketBall 강백호 = new 강백호();
강백호.shoot(); // 슬램덩크 슛
강백호.dribble(); // 달리기 드리블
BasketBall 정대만 = new 정대만();
정대만.shoot(); // 3점 슛
정대만.dribble(); // 달리기 드리블
BasketBall 송태섭 = new 송태섭();
송태섭.shoot(); // 레이업 슛
송태섭.dribble() // 풰이크 드리블
// 기능 변경
강백호.setShoot(new Point3Shoot());
강백호.shoot(); // 3점슛
}
전략패턴이란 무언가(어떤 객체) 어떤 기능(행동)이 있을 때, 그 기능을 쉽게 수정하기 위해서, 해당 알고리즘을 직접 구현하지 않고 외부 클래스로 빼내서 그 일을 위임시키는 것이다.
ex) 네비게이션 경로 검색
1. 걷기 도로
2. 대중교통
3. 자전거 도로
이처럼 네비게이션은 경로라는 기능을 검색하는데 이 중 어느하나를 선택한다.
이 때, 각각의 로직이 바뀔수도 있고, 추가될수도 있기 떄문에, 이걸 편히 하기위한 패턴이다.