수수한 코딩세상

[디자인 패턴] 전략 패턴 (Strategy Pattern, 스트래티지 패턴) 본문

수수한 코딩세상/디자인 패턴

[디자인 패턴] 전략 패턴 (Strategy Pattern, 스트래티지 패턴)

수수한 코딩열공생 2024. 6. 5. 21:58

스트래티지 패턴(Strategy Pattern)은 여러 알고리즘을 하나의 추상적인 접근점을 만들어 접근점에서 서로 교환가능하도록 해주는 패턴입니다.

  • 추상적인 접근 : 인터페이스(interface) or 추상클래스(abstract class)
  • 교환가능 : 추상적인 클래스끼리 교환 가능하게

 

기본적인 스트래티지 패턴 다이어그램

기본적인 스트래티지 패턴 다이어그램 (출처 : https://www.youtube.com/watch?v=UEjsbd3IZvA)

  • 행위를 클래스로 캡슐화 해서 동적으로 행위를 자유롭게 바꿀 수 있는 패턴
  • 전략을 쉽게 바꿀 수 있도록 해주는 패턴
  • 구체적인 것을 추상화해서 바라볼 수 있도록 하는 패턴

 

다음 예제 요구사항을 통해 스트래티지의 사용 예를 살펴보고자 합니다.

 

예제 요구사항

  • 신작게임에서 캐릭터의 무기를 구현해야 한다.
  • 무기는 두가지 종류가 있다.
    • 칼 (Knife)
    • 검 (Sword)
public interface Weapon {
    //무기들의 접근점 역할을 하는 interface
    public int doAttack();

}
public class Knife implements Weapon{

    @Override
    public int doAttack(){
        System.out.println("칼 공격");
        return 0;
    }
}
public class Sword implements Weapon{

    @Override
    public int doAttack(){
        System.out.println("검 공격");
        return 0;
    }
}
public class GameCharacter {

    //접근점 생성
    private Weapon weapon;

    //setWeapon() 함수를 통해 교환 가능
    public void setWeapon(Weapon weapon){
        this.weapon=weapon;
    }

    public int attack(){
        if(weapon==null){
            System.out.println("맨손 공격");
        }
        else{
            //델리게이트
            //어떤 무기를 들고 있는지는 Weapon 객체가 알아서 바꿔주고
            //게임 캐릭터는 그냥 공격만 하게된다
            weapon.doAttack();
        }
        return 0;
    }
}
public class Main {
    public static void main(String[] args) {

        System.out.println("Hello world!");

        //캐릭터 생성
        GameCharacter character = new GameCharacter();

        //무기가 할당되지 않을때
        character.attack();

        //칼 할당
        character.setWeapon(new Knife());
        character.attack();

        //검 할당
        character.setWeapon(new Sword());
        character.attack();

    }
}

GameCharacter Class를 보면 공격만 할 뿐 자신이 어떤 무기를 들고 공격하는지는 Weapon 객체가 알아서 바꿔주기 때문에 게임캐릭터는 무기가 무엇인지 모른 채 동작을 하는 것을 알 수 있습니다. 이처럼 어떤 무기(전략)를 쓸지는 모른 채 weapon 객체가 알아서 하도록 위임해 버리는 것입니다. 그리고 모든 무기는 Weapon이라는 인터페이스 클래스를 상속받아 구현하기 때문에 코드 확장성에도 열려있습니다. 

다음 유지보수 요구사항을 보면 코드 확장성에 열려있는 사실을 알 수 있습니다.

 

유지보수 요구사항

  • 무기 중에 도끼(Ax)를 추가해 주세요.
public class Ax implements Weapon{

    @Override
    public int doAttack(){
        
        System.out.println("도끼 공격");
        return 0;
    }
}
public class Main {
    public static void main(String[] args) {

        System.out.println("Hello world!");

        //캐릭터 생성
        GameCharacter character = new GameCharacter();

        //무기가 할당되지 않을때
        character.attack();

        //칼 할당
        character.setWeapon(new Knife());
        character.attack();

        //검 할당
        character.setWeapon(new Sword());
        character.attack();

        //도끼 할당
        character.setWeapon(new Ax());
        character.attack();
    }
}

다른 클래스의 코드를 수정할 필요 없이 도끼 클래스만 구현해주면 쉽게 무기(전략)를 추가해 줄 수 있습니다.

 

Strategy Pattern Class Diagram

예제 코드 클래스 다이어그램 (출처 : https://www.youtube.com/watch?v=UEjsbd3IZvA)

 

 


Reference

해당 글은 스토리지님의 디자인패턴 강의를 보고 정리한 내용입니다.

https://www.youtube.com/watch?v=UEjsbd3IZvA