전략 패턴(strategy pattern)

아이고마워·2022년 9월 5일
0

Design Pattern

목록 보기
1/1

오늘 제가 2시간동안 슬램덩크 요약본을 너무 재밋게 봤습니다.
농구 게임에 캐릭터가 있습니다. 기본적으로 이 있고, 드리블이 있죠.

  1. 레이업 슛
  2. 슬램 덩크 슛
  3. 3점 슛

드리블

  1. 달리기 드리블
  2. 풰이크 드리블
  3. 회전 드리블

먼저 이런식으로 기본기능들을 가진 드리블행동이라고 표현할 수 있습니다.

우리회사의 열정적인 기획팀장님의 요구사항이 추가되다 보면
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;
    }
}
  1. 행동 집합을 정의한 인터페이스를 선언해 줍니다. 이 부모 클래스를 상속받은 인스턴스에서는 여기 있는 인터페이스 타입으로 행동을 할당해줍니다.
    // 인스턴스 클래스
    public class 강백호 extends BasketBall{
        __constructor(){
            shootInterface = new SlamdunkShoot();
            dribbleInterface = new Dribble();
        }
    }
  2. 각 행동들의 실제 구현은 외부 클래스로 위임해주었으므로, 이 행동들을 호출할 수 있는 함수를 선언해 주었습니다(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. 자전거 도로
이처럼 네비게이션은 경로라는 기능을 검색하는데 이 중 어느하나를 선택한다.
이 때, 각각의 로직이 바뀔수도 있고, 추가될수도 있기 떄문에, 이걸 편히 하기위한 패턴이다.

0개의 댓글