괴발나라

[GOF] 전략 패턴으로 비행기 게임 만들기 🛫🛬 본문

도서/JAVA 객체지향 디자인패턴

[GOF] 전략 패턴으로 비행기 게임 만들기 🛫🛬

괴발맨 2022. 2. 4. 21:14

오늘은 전략 패턴에 대해 알아보겠습니다.
위키백과의 전략 패턴에 대한 설명은 다음과 같습니다.

 

"The strategy pattern is a behavioral software design pattern
that enables selecting an algorithm at runtime."

 

대충 알고리즘(기능)을 런타임 시점(실행 중)에 동적으로 선택할 수 있게 해준다고 합니다.

이게 무슨 소리일까요?
설명하기 어렵네요. 바로 예시를 봅시다.


✈ 비행기 만들기 ✈

1942 라는 게임을 아시나요?
게임 화면을 보시면 바로 아실 겁니다.

오락실 게임 1942

게이머는 위 화면 하단에 있는 작은 비행기를 조종합니다.
비행기로 적들을 공격하며 물리치죠.
그러면 이 비행기를 클래스로 만들어 봅시다!

public class Game1942 {
    public static void main(String[] args) {
        Flight fligth = new Flight(); // 비행기 객체 생성
        fligth.attack() // 뾱뾱뾱뾱뾱 
    }
}

class Flight {
    void attack() {
        System.out.println("뾱뾱뾱뾱뾱")
    }
    void move() {
        // 이동 기능...
    }
}

비행기가 아직 어떤 아이템도 먹지 못해서
"뾱뾱뾱" 같은 허접한 공격을 할 수 밖에 없네요 😥


아이템을 먹으면 다음과 같이 공격 기능이 변경됩니다!

 

  • 기관총 아이템 : "둥둥둥둥"
  • 로켓 아이템    : "슈우욱~ 펑!"

공격 기능을 바꾸려면 다음과 같이 코드를 변경해야 합니다.

class Flight {
    void attack() {
        System.out.println("둥둥둥둥")
    }
    void move() {
        // 이동 기능...
    }
}

이번엔 로켓 공격으로 바꿔봅시다.

class Flight {
    void attack() {
        System.out.println("슈우욱~ 펑!")
    }
    void move() {
        // 이동 기능...
    }
}

그런데 문제가 있습니다.
서로 다른 아이템을 먹은 비행기들이 같은 공격을 하게 됩니다. 😮

public class Game1942 {
    public static void main(String[] args) {
        Flight defaultFlight = new Flight(); // 아이템 못 먹은 비행기
        defaultFlight.attack(); // 뾱뾱뾱뾱뾱

        Flight machineGunFlight = new Flight(); // 기관총 아이템 먹은 비행기
        machineGunFlight.attack(); // 뾱뾱뾱뾱뾱
    }
}

class Flight {
    void attack() {
        System.out.println("뾱뾱뾱뾱뾱")
    }
    void move() {
        // 이동 기능...
    }
}

게다가 공격 기능을 바꾸려면,
기존 코드를 지우고 새로운 기능을 작성하는 작업을 반복해야 합니다.


얼마나 번거롭나요..
이제 전략 패턴을 이용해 개선시켜보겠습니다!


🤖 전략 패턴 적용하기 🤖

전략 패턴은 변경되는 부분을 인터페이스 뒤로 캡슐화 시키는 디자인 패턴입니다.
위 코드에서 변경되는 부분은 공격 기능입니다.


하나의 공격 인터페이스를 만들고,
구체적인 각각의 공격 기능은 공격 인터페이스의 구현 클래스로 만들겠습니다.

// 공격 인터페이스
interface AttackStrategy {
    void attack();
}
// 기본 공격
class DefaultAttackStrategy implements AttackStrategy {
    void attack() {
        System.out.print("뾱뾱뾱뾱뾱");
    }
}
// 기관총 공격
class MachineGunAttackStrategy implements AttackStrategy {
    void attack() {
        System.out.println("둥둥둥둥둥");
    }
}
// 로켓 공격
class RocketAttackStrategy implements AttackStrategy {
    void attack() {
        System.out.println("둥둥둥둥둥");
    }
}

그리고 기존의 비행기 클래스의 코드가 공격 인터페이스를 사용하도록 변경시켜보겠습니다.

class Flight {
    void attack(AttackStrategy attackStrategy) {
        attackStrategy.attack();
    }

    void move() {
        // 이동 기능...
    }
}

이제 1942 게임에서 이 비행기를 사용해봅시다!

public class Game1942 {
    public static void main (String[] args) {
        Flight flight = new Flight();

        flight.attack(new DefaultAttackStrategy()); // 기본 공격

        flight.attack(new MachineGunAttackStrategy()); // 기관총 공격

        flight.attack(new RocketAttackStrategy()); // 로켓 공격
    }
}

이제 공격 기능을 마음대로 바꿀 수 있게 되었습니다!


비행기 클래스에게는 공격 인터페이스만 보여주고
구체적인 공격 기능은 숨겨놨기 때문에 가능한 것입니다.

 

전략 패턴을 사용하면

이렇게 구체적인 전략을 뒤로 숨겨서
실행 시 입맛따라 전략을 바꿀 수 있습니다.

 

한번 직접 게임 캐릭터를 만들어 전략 패턴을 구현해 보면 재밌을 것 같습니다.

감사합니다. 🙏