전략 패턴 (Strategy Pattern)

정승현·2024년 11월 13일

💡전략패턴이란?

유연한 알고리즘 교체를 위한 디자인 패턴
실행 중에 알고리즘을 선택할 수 있게 하는 행위 디자인 패턴, 객체가 할 수 있는 행위들을 전략으로 만들어 놓고, 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴

✍️ 전략패턴 사용 이유

  • 유연성 확보
    • 알고리즘을 사용하는 코드를 변경하지 않고도 새로운 알고리즘을 추가하거나 변경할 수 있다.
    • 기존 코드를 건드리지 않고 새로운 전략을 추가할 수 있어 OCP(개방-폐쇄 원칙)를 만족한다.
  • 코드 재사용성 향상

    • 동일한 전략을 다른 컨텍스트에서도 재사용할 수 있다.
    • 중복 코드를 줄이고 유지보수성을 높일 수 있다.
  • 알고리즘의 캡슐화

    • 알고리즘의 세부 구현을 사용자로부터 숨길 수 있다.
    • 클라이언트 코드는 구체적인 구현을 알 필요 없이 인터페이스만 알면 된다.

    오리 시뮬레이션 게임

    1. Fly 기능 추가
    2. 고무 인형 추가

🤔 날지 못하는 오리가 계속 추가되야하고, 모형오리처럼 날지도 못하고 소리도 못내는 오리들도 추가가 되야한다면?

  • Quack 과 Fly 를 인터페이스로 구현해서 필요한 클래스에서 구현하면 해결?
    • 똑같이 "꽥" 우는 오리가 많으면 코드 중복
    • 만약 오리 울음소리를 "꽥꽥" 으로 변경해야 한다면 모든 구현체에서 변경해야 하는 문제 발생

✍️전략패턴의 구조


이미지 출처 : 인파님 tistory - 전략패턴 완벽 마스터하기

  • Strategy (전략 인터페이스)
    • 모든 전략들이 공통적으로 구현해야 하는 인터페이스
    • 알고리즘군을 대표하는 공통 메서드를 선언
  • Concrete Strategies (구체적인 전략)
    • Strategy 인터페이스를 구현하는 구체적인 알고리즘 클래스들
    • 각각의 전략이 실제로 어떻게 동작할지를 구현
  • Context (컨텍스트)
    • Strategy 타입의 필드를 가지고 있음
    • 전략 객체를 받아서 사용하는 클래스
    • 전략 객체의 메서드를 호출하여 실제 작업을 위임
  • Client (클라이언트)
    • Context에 전략을 주입하고 실행을 요청하는 주체
    • 어떤 전략을 사용할지 선택하고 Context에 전달

💡 오리 시뮬레이션 게임 전략 패턴 적용하기

  • Strategy (전략 인터페이스)

    // 나는 행동 전략
    public interface FlyBehavior {
       void fly();
    }
    // 울음 소리 전략
    public interface QuackBehavior {
       void quack();
    }
    
  • Concrete Strategies (구체적인 전략)

    // 나는 행동 구현
    public class FlyWithWings implements FlyBehavior {
       public void fly() {
           System.out.println("날개로 날아갑니다!");
       }
    }
    public class FlyNoWay implements FlyBehavior {
       public void fly() {
           System.out.println("저는 날 수 없어요");
       }
    }
    // 울음 소리 구현
    public class Quack implements QuackBehavior {
       public void quack() {
           System.out.println("꽥꽥!");
       }
    }
    public class Squeak implements QuackBehavior {
       public void quack() {
           System.out.println("삑삑!");
       }
    }
  • Context (컨텍스트)

    public abstract class Duck {
       protected FlyBehavior flyBehavior;      // 전략 객체 참조
       protected QuackBehavior quackBehavior;  // 전략 객체 참조
       
       public void performFly() {
           flyBehavior.fly();  // 전략 위임
       }
       
       public void performQuack() {
           quackBehavior.quack();  // 전략 위임
       }
    }
    
  • Client (클라이언트)

    public class MallardDuck extends Duck {
       public MallardDuck() {
           flyBehavior = new FlyWithWings();    
           quackBehavior = new Quack();         
         }
     }
    public class RubberDuck extends Duck {
       public RubberDuck() {
           flyBehavior = new FlyNoWay();        
           quackBehavior = new Squeak();        
         }
     }
  • 호출

        Duck mallard = new MallardDuck();
        mallard.display();
        mallard.performFly();
        mallard.performQuack();

        System.out.println();

        Duck modelDuck = new ModelDuck();
        modelDuck.display();
        modelDuck.performQuack();
        modelDuck.performFly();
        modelDuck.setFlyBehavior(new FlyRocketPowered());
        modelDuck.performFly();
        System.out.println();

Reference

  • 헤드퍼스트 디자인패턴 [한빛미디어]
profile
게시글 업로드중..⌛

0개의 댓글