13-1. 전략 패턴 (Strategy Pattern)

박은서's avatar
Feb 24, 2026
13-1. 전략 패턴 (Strategy Pattern)

1. 전략 패턴 (Strategy Pattern)

1️⃣ 전략 패턴이란?

행위를 객체로 분리해서, 실행 시점에 원하는 알고리즘(전략)을 선택·교체할 수 있도록 만드는 행동 패턴

2️⃣ 전략 패턴의 필요성 (문제 상황)

❌ if-else 지옥

if (paymentType.equals("CARD")) { ... } else if (paymentType.equals("BANK")) { ... } else if (paymentType.equals("KAKAO")) { ... }

문제점

  • 새로운 기능 추가 시 기존 코드 수정
  • OCP(개방-폐쇄 원칙) 위반
  • 테스트 어려움
  • 유지보수 비용 증가

3️⃣ 핵심 아이디어

➡️ "바뀌는 부분(알고리즘)을 따로 빼라"
  • 공통 동작은 유지
  • 변하는 알고리즘만 객체로 분리
  • 실행 중 전략 교체 가능

4️⃣ 구성 요소 (3요소)

1) Strategy (전략 인터페이스)

역할 : 공통 동작 정의
public interface PaymentStrategy { void pay(int amount); }

2) ConcreteStrategy (구체 전략)

역할 : 실제 알고리즘 구현
public class CardPayment implements PaymentStrategy { public void pay(int amount) { System.out.println("카드 결제: " + amount); } }
public class BankTransfer implements PaymentStrategy { public void pay(int amount) { System.out.println("계좌 이체: " + amount); } }

3) Context (전략을 사용하는 객체)

역할 : 전략을 주입받아 실행
public class PaymentContext { private PaymentStrategy strategy; public PaymentContext(PaymentStrategy strategy) { this.strategy = strategy; } public void execute(int amount) { strategy.pay(amount); } }

5️⃣ 사용 예

PaymentStrategy strategy = new CardPayment(); PaymentContext context = new PaymentContext(strategy); context.execute(10000);
👉 전략을 바꾸고 싶다면?
context = new PaymentContext(new BankTransfer());
코드 수정 없이 전략 교체 가능

6️⃣ 구조 요약

[Context] ----> [Strategy 인터페이스] ▲ ┌──────────────┴──────────────┐ [ConcreteStrategy A] [ConcreteStrategy B]

7️⃣ 전략 패턴의 장단점

1) 장점

✔ 알고리즘 독립적 관리
✔ OCP 준수 (확장에는 열려 있고, 수정에는 닫혀 있음)
✔ 런타임 전략 교체 가능
✔ 테스트 용이
✔ 코드 가독성 향상

2) 단점

✖ 클래스 수 증가
✖ 단순한 경우엔 과설계
✖ 전략 객체 생성 비용 고려 필요

8️⃣ 전략 패턴을 써야 하는 상황

  • 동일한 기능에 여러 알고리즘이 존재할 때
  • 조건문이 계속 늘어날 때
  • 런타임에 동작을 바꿔야 할 때
  • 정책(Policy)을 외부에서 주입해야 할 때

9️⃣ 전략 패턴 vs 다른 패턴 비교

패턴
목적
Strategy
알고리즘 교체
Template Method
알고리즘 골격 고정
State
상태에 따라 행동 변경
Command
요청을 객체로 캡슐화

2. 실습 (ex01)

1️⃣ 추상화 이전

1) Mouse.java

C:\workspace\java_lab\designapp\src\ex01\Mouse.java
package ex01; public class Mouse { private String name = "쥐"; public String getName() { return name; } }

2) Tiger.java

C:\workspace\java_lab\designapp\src\ex01\Tiger.java
package ex01; public class Tiger { private String name = "호랑이"; public String getName() { return name; } }

3) Doorman.java

C:\workspace\java_lab\designapp\src\ex01\Doorman.java
package ex01; public class Doorman { public void 쫓아내(Tiger a) { System.out.println(a.getName() + " 쫓아내"); } }

4) App.java

C:\workspace\java_lab\designapp\src\ex01\App.java
package ex01; public class App { public static void main(String[] args) { Tiger tiger = new Tiger(); Doorman doorman = new Doorman(); doorman.쫓아내(tiger); } }

5) 결과

notion image
💡
doorman의 쫓아내() 메서드는 구체적인 것(Tiger)에 의존하고 있기 때문에 매개변수에 Mouse를 넣으면 예외 터짐

2️⃣ 추상화

1) Mouse.java

package ex01; public class Mouse extends Animal { private String name = "쥐"; public String getName() { return name; } }

2) Tiger.java

package ex01; public class Tiger extends Animal { private String name = "호랑이"; public String getName() { return name; } }

3) Animal.java

C:\workspace\java_lab\designapp\src\ex01\Animal.java
package ex01; public abstract class Animal { public abstract String getName(); }

4) Doorman.java

package ex01; public class Doorman { public void 쫓아내(Animal a) { System.out.println(a.getName() + " 쫓아내"); } }

5) App.java

package ex01; // SOLID : 객체지향원칙 (D, O) // DIP : 추상적인 것에 의존하라! -> 추상적인 것에 의존하면 자동으로 OCP가 됨 // OCP : 새로운 코드에는 OPEN, 기존 코드에는 CLOSE public class App { public static void main(String[] args) { Tiger tiger = new Tiger(); Mouse mouse = new Mouse(); Doorman doorman = new Doorman(); doorman.쫓아내(tiger); doorman.쫓아내(mouse); } }

6) 결과

notion image
Share article