5주차 Unit 6.3 — 전략 패턴

Psj·2026년 5월 27일

F-lab

목록 보기
174/230

Unit 6.3 — 전략 패턴

F-LAB JAVA · 5주차 · Phase 6 · 객체지향 설계 원칙 (OCP & 전략 패턴)
🏆 Phase 6 완주 — 지금까지의 진화를 패턴으로 명명


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • 전략 패턴 (Strategy Pattern) 의 정의는?
  • Context / Strategy / ConcreteStrategy 구성 요소는?
  • ShipmentDao 와 ConnectionMaker 의 매핑 은?
  • 전략을 외부에서 주입 받는 방식은?
  • 전략 패턴 = OCP 구현 도구인 이유는?
  • 전략 패턴 vs 템플릿 메소드 패턴 의 차이는?
  • Spring 의 전략 패턴 사례 는?
  • 전략 패턴의 장점 은?
  • Phase 6 전체 의 종합은?

🎯 핵심 한 문장

전략 패턴은 변경되는 알고리즘을 인터페이스로 분리하고 구체 구현을 외부에서 주입받는 패턴으로, ShipmentDao (Context) 가 ConnectionMaker (Strategy) 인터페이스에 의존하고 N/DConnectionMaker (ConcreteStrategy) 를 주입받는 것이 바로 이 패턴이다.
전략 패턴의 구성 요소는 Context (전략을 사용하는 주체), Strategy (전략 인터페이스), ConcreteStrategy (구체 전략 구현) 다.
우리가 Phase 6 에서 만든 구조에서 ShipmentDao 가 Context, ConnectionMaker 가 Strategy, N/DConnectionMaker 가 ConcreteStrategy 에 정확히 대응한다.
전략은 외부에서 생성자 등으로 주입 되며, 이로써 새 전략 (ConcreteStrategy) 을 추가하면 Context 코드 변경 없이 알고리즘을 교체할 수 있어 전략 패턴이 곧 OCP 의 구현 도구 가 된다.
전략 패턴은 합성 (전략 주입) 기반이라는 점에서 상속 기반의 템플릿 메소드 패턴과 구별되며, Spring 곳곳 (Comparator, Resource, PlatformTransactionManager 등) 에서 활용된다.

비유 — 내비게이션 경로 옵션

전략 패턴 = 내비게이션 경로 선택:

Context (내비게이션 앱):
  - 길 안내 (전략 사용)
  - "경로 계산해줘"

Strategy (경로 알고리즘 인터페이스):
  - calculateRoute()
  - 계약만

ConcreteStrategy (구체 경로):
  - 최단 거리 전략
  - 최소 시간 전략
  - 무료 도로 전략

주입:
  - 사용자가 전략 선택
  - 앱에 주입
  - 앱은 어떤 전략인지 모름 (인터페이스만)

OCP:
  - 새 전략 (자전거 경로) 추가
  - 앱 코드 변경 X
  - 전략만 추가 (확장)

ShipmentDao = 내비 앱 (Context)
ConnectionMaker = 경로 알고리즘 (Strategy)
N/DConnectionMaker = 구체 경로 (ConcreteStrategy)

→ 전략 패턴 = 알고리즘 인터페이스 분리 + 주입, Context/Strategy/ConcreteStrategy.


🧭 9개 섹션 로드맵

1. 전략 패턴의 정의
2. 세 가지 구성 요소
3. ShipmentDao와 ConnectionMaker 매핑
4. 전략 주입
5. 전략 패턴 = OCP 구현
6. 전략 vs 템플릿 메소드
7. Spring의 전략 패턴
8. Phase 6 완주 정리
9. 면접 + 자기 점검

1️⃣ 전략 패턴의 정의

1.1 정의

전략 패턴 (Strategy Pattern):

  변경되는 알고리즘을 인터페이스로 분리,
  구체 구현을 외부에서 주입.

  - 알고리즘 = 전략
  - 인터페이스로 추상화
  - 런타임 교체

1.2 GoF 패턴

GoF 디자인 패턴:

  행위 패턴 (Behavioral):
    - 알고리즘군 정의
    - 캡슐화
    - 교체 가능

  "알고리즘을 정의하고
   캡슐화하여 교체 가능하게"

1.3 의도

의도:

  - 알고리즘 캡슐화
  - 런타임 선택
  - 조건 분기 제거
  - 확장 (새 전략)

1.4 ILIC 의 맥락

// 전략 패턴 — 운임 계산
public interface FreightStrategy {   // Strategy
    BigDecimal calculate(Shipment shipment);
}

public class ShipmentService {   // Context
    private final FreightStrategy freightStrategy;
    
    public ShipmentService(FreightStrategy strategy) {
        this.freightStrategy = strategy;   // 전략 주입
    }
    
    public BigDecimal getFreight(Shipment s) {
        return freightStrategy.calculate(s);   // 전략 사용
    }
}

// ConcreteStrategy 들
class SeaFreightStrategy implements FreightStrategy {
    public BigDecimal calculate(Shipment s) {
        return s.getWeight().multiply(BigDecimal.valueOf(10));
    }
}
class AirFreightStrategy implements FreightStrategy {
    public BigDecimal calculate(Shipment s) {
        return s.getWeight().multiply(BigDecimal.valueOf(50));
    }
}

1.5 자기 점검 답변

전략 패턴 (Strategy Pattern) 의 정의는?

:
1. 정의:

  • 알고리즘 인터페이스 분리
  • 외부 주입
  1. GoF:

    • 행위 패턴
  2. 의도:

    • 알고리즘 캡슐화
    • 교체
  3. 요소:

    • Context/Strategy

2️⃣ 세 가지 구성 요소

2.1 세 요소

전략 패턴 3요소:

1. Context
   - 전략 사용 주체

2. Strategy (인터페이스)
   - 전략 계약

3. ConcreteStrategy
   - 구체 전략 구현

2.2 Context

Context:

  - 전략 보유 (합성)
  - 전략 호출
  - 구체 전략 모름

  ShipmentDao

2.3 Strategy

Strategy (인터페이스):

  - 알고리즘 계약
  - 추상화

  ConnectionMaker

2.4 ConcreteStrategy

ConcreteStrategy:

  - 구체 알고리즘
  - Strategy 구현

  N/DConnectionMaker

2.5 구조 시각화

구조:

[Context]
  - strategy (Strategy)
  - execute() { strategy.algorithm(); }
        ↓ 사용
[Strategy] (인터페이스)
  - algorithm()
        ↑ 구현
[ConcreteStrategyA] [ConcreteStrategyB]

2.6 ILIC 의 맥락

// 3요소 (ILIC)

// Strategy (인터페이스)
public interface ConnectionMaker {
    Connection makeConnection() throws Exception;
}

// Context
public class ShipmentDao {
    private final ConnectionMaker connectionMaker;   // 전략 보유
    
    public ShipmentDao(ConnectionMaker connectionMaker) {
        this.connectionMaker = connectionMaker;
    }
    
    public void add(Shipment s) throws Exception {
        Connection c = connectionMaker.makeConnection();   // 전략 사용
    }
}

// ConcreteStrategy 들
public class NConnectionMaker implements ConnectionMaker {
    public Connection makeConnection() throws Exception { return null; }
}
public class DConnectionMaker implements ConnectionMaker {
    public Connection makeConnection() throws Exception { return null; }
}

2.7 자기 점검 답변

Context / Strategy / ConcreteStrategy 구성 요소는?

:
1. Context:

  • 전략 사용 주체
  1. Strategy:

    • 전략 인터페이스
  2. ConcreteStrategy:

    • 구체 구현
  3. 구조:

    • Context → Strategy ← Concrete

3️⃣ ShipmentDao와 ConnectionMaker 매핑

3.1 정확한 매핑

전략 패턴ILIC
ContextShipmentDao
StrategyConnectionMaker
ConcreteStrategyN/DConnectionMaker
algorithm()makeConnection()

3.2 Context = ShipmentDao

Context = ShipmentDao:

  - ConnectionMaker 보유
  - makeConnection 호출
  - 구체 모름

→ 전략 사용 주체

3.3 Strategy = ConnectionMaker

Strategy = ConnectionMaker:

  - 연결 알고리즘 계약
  - makeConnection()
  - 인터페이스

→ 전략 추상화

3.4 우리가 만든 것

우리가 만든 것:

  Phase 6.1 에서:
    - 인터페이스 + 주입

  사실은:
    - 전략 패턴

→ 패턴 이름 부여

3.5 ILIC 의 맥락

// Phase 6.1~6.2 의 코드 = 전략 패턴

// Strategy (Phase 6.1 의 ConnectionMaker)
public interface ConnectionMaker {
    Connection makeConnection() throws Exception;   // algorithm()
}

// Context (Phase 6.1 의 ShipmentDao)
public class ShipmentDao {
    private final ConnectionMaker connectionMaker;   // 전략 보유
    public ShipmentDao(ConnectionMaker cm) { this.connectionMaker = cm; }
    public void add(Shipment s) throws Exception {
        Connection c = connectionMaker.makeConnection();   // 전략 사용
    }
}

// ConcreteStrategy (Phase 6.1 의 구현들)
public class CustomerAConnectionMaker implements ConnectionMaker {
    public Connection makeConnection() throws Exception { return null; }
}

// → 우리가 만든 게 정확히 전략 패턴

3.6 자기 점검 답변

ShipmentDao와 ConnectionMaker의 매핑은?

:
1. Context:

  • ShipmentDao
  1. Strategy:

    • ConnectionMaker
  2. ConcreteStrategy:

    • N/DConnectionMaker
  3. 우리가 만든 것:

    • 전략 패턴

4️⃣ 전략 주입

4.1 주입 방식

전략 주입:

  생성자 주입:
    - 생성 시 전략 받음

  Setter 주입:
    - 나중에 변경

  → 외부에서 전략 결정

4.2 생성자 주입

// 생성자 주입
public class ShipmentDao {
    private final ConnectionMaker connectionMaker;
    
    public ShipmentDao(ConnectionMaker connectionMaker) {
        this.connectionMaker = connectionMaker;   // 주입
    }
}

// 사용
ShipmentDao dao = new ShipmentDao(new NConnectionMaker());

4.3 Setter 주입

// Setter 주입 (런타임 변경 가능)
public class ShipmentDao {
    private ConnectionMaker connectionMaker;
    
    public void setConnectionMaker(ConnectionMaker cm) {
        this.connectionMaker = cm;   // 변경 가능
    }
}

// 런타임 전략 변경
dao.setConnectionMaker(new DConnectionMaker());

4.4 런타임 선택

// 런타임 전략 선택
ConnectionMaker strategy = switch (config.getDbType()) {
    case "mysql" -> new MySqlConnectionMaker();
    case "oracle" -> new OracleConnectionMaker();
    default -> throw new IllegalArgumentException();
};
ShipmentDao dao = new ShipmentDao(strategy);
// 설정에 따라 런타임 결정

4.5 ILIC 의 맥락

// 전략 주입 (ILIC)
public class ShipmentDaoConfig {
    
    public ShipmentDao createDao(String customerType) {
        // 고객사별 전략 선택 (런타임)
        ConnectionMaker strategy = switch (customerType) {
            case "A" -> new CustomerAConnectionMaker();
            case "B" -> new CustomerBConnectionMaker();
            default -> throw new IllegalArgumentException();
        };
        // 전략 주입
        return new ShipmentDao(strategy);
        // 이 분기조차 IoC 컨테이너가 대신 (Phase 8)
    }
}
// 전략 결정/주입을 외부가 담당

4.6 자기 점검 답변

전략을 외부에서 주입받는 방식은?

:
1. 주입:

  • 생성자/Setter
  1. 생성자:

    • 불변, 필수
  2. Setter:

    • 런타임 변경
  3. 선택:

    • 런타임 결정

5️⃣ 전략 패턴 = OCP 구현

5.1 OCP 구현 도구

전략 패턴 = OCP 구현:

  새 전략 (ConcreteStrategy):
    - 추가 (확장 ✅)

  Context:
    - 변경 X (닫힘 ✅)

  → OCP 달성

5.2 확장 (새 전략)

// 새 전략 추가 (확장)
public class PostgreSqlConnectionMaker implements ConnectionMaker {
    public Connection makeConnection() throws Exception {
        return null;   // 새 전략
    }
}
// Context (ShipmentDao) 변경 X

5.3 분기 제거

분기 제거:

전 (OCP 위반):
  if (type) { ... } else if ...

후 (전략 패턴):
  strategy.algorithm()
  - 분기 X
  - 다형성

5.4 전략 vs 분기

전략 vs 분기:

분기 (if-else):
  - 새 케이스 = 수정
  - OCP 위반

전략 패턴:
  - 새 전략 = 추가
  - OCP 준수

5.5 ILIC 의 맥락

// 전략 패턴으로 OCP

// ❌ 분기 (OCP 위반)
public BigDecimal calculateFreight(Shipment s, String mode) {
    if (mode.equals("SEA")) return seaCalc(s);
    else if (mode.equals("AIR")) return airCalc(s);
    // 새 운송 → 수정
    throw new IllegalArgumentException();
}

// ✓ 전략 패턴 (OCP)
interface FreightStrategy {
    BigDecimal calculate(Shipment s);
}
class ShipmentService {
    private final FreightStrategy strategy;
    ShipmentService(FreightStrategy s) { this.strategy = s; }
    BigDecimal getFreight(Shipment s) {
        return strategy.calculate(s);   // 분기 X
    }
}
// 새 운송 = 새 FreightStrategy 구현 (확장, Service 변경 X)
class SeaFreightStrategy implements FreightStrategy {
    public BigDecimal calculate(Shipment s) { return s.getWeight(); }
}

5.6 자기 점검 답변

전략 패턴 = OCP 구현 도구인 이유는?

:
1. OCP 구현:

  • 새 전략 (확장)
  • Context 불변 (닫힘)
  1. 확장:

    • 새 ConcreteStrategy
  2. 분기 제거:

    • 다형성
  3. vs 분기:

    • 추가 vs 수정

6️⃣ 전략 vs 템플릿 메소드

6.1 차이

항목전략 패턴템플릿 메소드
방식합성 (주입)상속 (서브클래스)
변경런타임컴파일 타임
알고리즘통째 교체일부 재정의
결합느슨강함

6.2 합성 vs 상속

합성 vs 상속:

전략 패턴 (합성):
  - 전략 객체 보유
  - 주입
  - 느슨

템플릿 메소드 (상속):
  - 서브클래스
  - 오버라이드
  - 강결합

6.3 런타임 vs 컴파일

런타임 vs 컴파일:

전략:
  - 런타임 전략 교체
  - 동적

템플릿:
  - 컴파일 타임 결정
  - 정적

6.4 선택

선택:

전략 패턴:
  - 알고리즘 통째 교체
  - 런타임 변경
  - 유연성

템플릿 메소드:
  - 흐름 고정, 일부만
  - 공통 흐름 강제

6.5 ILIC 의 맥락

// 전략 패턴 (합성) vs 템플릿 메소드 (상속)

// 전략 패턴 — 합성 (권장)
class ShipmentDaoStrategy {
    private final ConnectionMaker connectionMaker;   // 합성
    ShipmentDaoStrategy(ConnectionMaker cm) { this.connectionMaker = cm; }
    // 런타임 전략 교체 가능
}

// 템플릿 메소드 — 상속
abstract class ShipmentDaoTemplate {
    abstract Connection getConnection();   // 상속
    // 컴파일 타임 결정
}

// 같은 문제, 다른 접근:
// - 전략: 합성, 런타임, 느슨 (선호)
// - 템플릿: 상속, 컴파일, 강결합
interface ConnectionMaker { Connection makeConnection() throws Exception; }

6.6 자기 점검 답변

전략 패턴 vs 템플릿 메소드 패턴의 차이는?

:
1. 방식:

  • 전략: 합성
  • 템플릿: 상속
  1. 변경:

    • 전략: 런타임
    • 템플릿: 컴파일
  2. 알고리즘:

    • 전략: 통째
    • 템플릿: 일부
  3. 결합:

    • 전략: 느슨
    • 템플릿: 강함

7️⃣ Spring의 전략 패턴

7.1 Spring 의 활용

Spring 전략 패턴 사례:

  - Comparator (정렬 전략)
  - Resource (리소스 접근 전략)
  - PlatformTransactionManager (트랜잭션 전략)
  - ViewResolver (뷰 해석 전략)
  - 곳곳에 인터페이스 + 주입

7.2 Comparator

// Comparator = 전략 패턴
List<Shipment> shipments = ...;

// 다른 정렬 전략
shipments.sort(Comparator.comparing(Shipment::getWeight));   // 무게
shipments.sort(Comparator.comparing(Shipment::getId));        // ID
// Comparator = 정렬 전략 (교체 가능)

7.3 DI 와 전략

DI 와 전략:

  Spring DI:
    - 인터페이스 주입
    - 전략 패턴 자연스럽게

  @Autowired:
    - 전략 구현 주입

7.4 빈으로 전략

// Spring 빈으로 전략 주입
@Service
public class ShipmentService {
    private final FreightStrategy freightStrategy;
    
    // 생성자 주입 (전략)
    public ShipmentService(FreightStrategy freightStrategy) {
        this.freightStrategy = freightStrategy;
    }
}

@Component
public class SeaFreightStrategy implements FreightStrategy {
    public BigDecimal calculate(Shipment s) { return s.getWeight(); }
}
// Spring 이 전략 주입 (DI = 전략 자동화)

7.5 ILIC 의 맥락

// Spring 으로 전략 패턴 (ILIC)

// 전략 인터페이스
public interface FreightStrategy {
    BigDecimal calculate(Shipment shipment);
}

// 전략 구현들 (빈)
@Component("sea")
public class SeaFreightStrategy implements FreightStrategy {
    public BigDecimal calculate(Shipment s) {
        return s.getWeight().multiply(BigDecimal.valueOf(10));
    }
}

@Component("air")
public class AirFreightStrategy implements FreightStrategy {
    public BigDecimal calculate(Shipment s) {
        return s.getWeight().multiply(BigDecimal.valueOf(50));
    }
}

// Context (빈 주입)
@Service
public class ShipmentService {
    private final Map<String, FreightStrategy> strategies;   // 전략 맵
    
    public ShipmentService(Map<String, FreightStrategy> strategies) {
        this.strategies = strategies;   // Spring 이 모든 전략 주입
    }
    
    public BigDecimal calculate(Shipment s, String mode) {
        return strategies.get(mode).calculate(s);   // 전략 선택
    }
}
// Spring DI = 전략 패턴의 자연스러운 구현

7.6 자기 점검 답변

Spring의 전략 패턴 사례는?

:
1. 사례:

  • Comparator
  • PlatformTransactionManager
  • Resource
  1. Comparator:

    • 정렬 전략
  2. DI 와 전략:

    • 인터페이스 주입
  3. 빈 주입:

    • Spring 이 전략 주입

8️⃣ Phase 6 완주 정리

8.1 Phase 6 학습 종합

Phase 6 — OCP & 전략 패턴

Unit 6.1 — 인터페이스로 결합도 낮추기
  - ConnectionMaker 인터페이스
  - 주입, 결합도 ↓

Unit 6.2 — OCP ★깊이
  - 확장 열림, 변경 닫힘
  - 디자인 패턴의 뿌리

Unit 6.3 — 전략 패턴
  - Context/Strategy/ConcreteStrategy
  - OCP 구현 도구

8.2 진화 과정

진화 과정 (Phase 3~6):

전통 DAO (혼재)
    ↓ 관심사 분리 (Phase 4)
메서드 추출, 추상클래스
    ↓ 디자인 패턴 (Phase 5)
템플릿/팩토리 메소드
    ↓ 인터페이스 + 합성 (Phase 6)
전략 패턴 (OCP, DIP)
    ↓ (다음)
IoC / DI (Phase 7~8)

8.3 핵심 통찰

Phase 6 핵심 통찰:

1. 인터페이스로 결합도 ↓
2. OCP (확장/변경)
3. 전략 패턴 (Context/Strategy)
4. 합성 > 상속
5. → 구현 결정 외부로 (IoC 향)

8.4 다음 Phase 예고

Phase 6 → Phase 7:
  - 전략 주입 → 제어의 역전

Phase 7 — IoC (7.1 ★깊이):
  - IoC 개념 (제어 역전)
  - 프레임워크 vs 라이브러리
  - IoC 컨테이너

8.5 자기 점검 답변

Phase 6의 종합은?

:
1. 3 Unit:

  • 인터페이스 결합도
  • OCP
  • 전략 패턴
  1. 진화:

    • 혼재 → 전략 패턴
  2. 핵심:

    • 인터페이스, OCP, 전략
  3. 다음:

    • IoC/DI

9️⃣ 면접 + 자기 점검

9.1 면접 단골 질문 매핑

Q핵심 답변
전략 패턴?알고리즘 인터페이스 + 주입
3요소?Context/Strategy/ConcreteStrategy
매핑?ShipmentDao/ConnectionMaker/N·D
주입?생성자/Setter
OCP 구현?새 전략 추가 (확장)
vs 템플릿?합성 vs 상속
Spring 사례?Comparator, DI
장점?런타임 교체, 분기 제거
분기 제거?다형성
다음?IoC

9.2 자기 점검 체크리스트

정의

  • 알고리즘 분리 + 주입

3요소

  • Context/Strategy/Concrete

매핑

  • ShipmentDao 등

주입

  • 생성자

OCP

  • 구현 도구

vs 템플릿

  • 합성 vs 상속

Spring

  • 사례

9.3 추가 심화 질문

Q1: 전략 패턴 vs 상태 패턴?

답:

  • 전략: 알고리즘 교체 (외부 선택)
  • 상태: 상태별 행동 (내부 전이)
  • 구조 유사, 의도 다름
  • 전략: 한 번, 상태: 전이

Q2: 람다와 전략 패턴?

답:

  • 함수형 인터페이스 전략
  • 람다로 전략 (클래스 X)
  • Comparator 람다
  • 간결한 전략

Q3: 전략이 많으면?

답:

  • 전략 클래스 증가
  • Map<String, Strategy> 관리
  • Spring 빈 자동 수집
  • enum + 전략 조합

Q4: 전략 패턴 단점?

답:

  • 클래스 증가
  • 클라이언트가 전략 알아야
  • 간단한 경우 과함
  • 람다로 완화

Q5: 전략 vs 데코레이터?

답:

  • 전략: 알고리즘 교체
  • 데코레이터: 기능 추가 (감싸기)
  • 전략: 1개 선택
  • 데코레이터: 여러 겹

🎯 핵심 요약 — 3줄 정리

1. 전략 패턴

  • 알고리즘을 인터페이스로 분리, 구체를 외부 주입
  • Context(ShipmentDao) / Strategy(ConnectionMaker) / ConcreteStrategy(N·D)

2. OCP 구현 도구

  • 새 전략 = 추가 (확장), Context 변경 X (닫힘)
  • if-else 분기 제거 (다형성)

3. 합성 기반

  • 전략 패턴(합성) vs 템플릿 메소드(상속)
  • Spring 곳곳 활용 (Comparator, DI) → IoC 로 발전

🏆 Phase 6 완주 — OCP & 전략 패턴

🌱 Phase 6 — OCP & 전략 패턴
  ✅ Unit 6.1 인터페이스로 결합도 낮추기
  ✅ Unit 6.2 OCP (개방폐쇄원칙) ★깊이
  ✅ Unit 6.3 전략 패턴 ← 여기, Phase 6 완주

→ 인터페이스 (결합도 ↓)
→ OCP (확장/변경)
→ 전략 패턴 (Context/Strategy)

📚 다음으로...

Phase 7 — 제어의 역전 (IoC)

Phase 7 — 제어의 역전 IoC (7.1 ★깊이)
  Unit 7.1 — IoC (제어의 역전) 개념 ★깊이
  Unit 7.2 — 프레임워크 vs 라이브러리
  Unit 7.3 — IoC 컨테이너의 역할

5주차 누적 진행

✅ Part A — 동시성 마무리 (7 Unit)
🌱 Part B — 토비의 스프링
  ✅ Phase 3~5 (9 Unit)
  ✅ Phase 6 — OCP & 전략 패턴 (3 Unit) ← 완주
  ⏭ Phase 7 — IoC (3 Unit)

총: 19/26 Unit

🏆 Phase 6 완주 — OCP & 전략 패턴

profile
Software Developer

0개의 댓글