HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
📝
남득윤 학습 저장소
/
객체 지향 프로그래밍
객체 지향 프로그래밍
/
디자인 패턴
디자인 패턴
/
Strategy Pattern
Strategy Pattern
Strategy Pattern

Strategy Pattern

💡
전략 바꾸기

Motivation

여러 클래스가 특정 역할에 대해 behavior 만 다르게구현 되는 경우가 많다.
이때 behavior logic (strategy)만 문리하여 그 알고리즘을 런타임에 선택할 수 있도록 하는것은 좋은 아이디어 이다.

Intent

  • Algorithms 들만 모아서 그룹을 만들어 상호 변경 가능하도록 구현하자

Implementation

notion image
  • Strategy - 모든 구체전략에 대한 인터페이스를 제공한다.
  • ConcreteStrategy - 구체 전략
  • Context
    • 구체 전략에대한 참조를 전략 인터페이스에 담아 보관하고 있음
    • 클라이언트의 요청이 들어올 시 실질적인 알고리즘의 실행은 구체 전략에 위임
 

Applicablity & Examples

notion image

Specific problems & Implementation

전략에 데이터 (Parameter/return) 주고 받기
보통 Strategy에는 데이터를 넘기고 받아야됨 두가지 방법이 있음
  • 주고 받기 위한 클래스를 따로 만듬
    • 단점 - 어떤 전략은 필드를 모두 필요 없음, 복잡함
  • 전략 객체 자체에 주고 받을 데이터를 위한 필드를 만듬
    • 단점 - 전략을 사용하는 문맥(Context)와 전략이 강하게 결함함
 
연관된 알고리즘의 그룹
  • 그루핑을 할 수도 있고 계층을 나눌 수 도 있음.
  • 이경우 Composite 디자인 패턴을 신중하게 사용해야함
 
 
Optionally Concrete Strategy Objects
Default 전략을 제공하여 전달받은 전략이 null인 경우 default 전략을 적용할 수 있음
 
 
전략패턴 + 생성패턴
클라이언트는 String과 같은 간단한 식별자만 전달 하여 여러 방식으로 생성된 객체를 사용할 수 있음
 
전략패턴과 브릿지패턴
  • 둘은 같은 UML 구조를 가지지만 Intent가 다름
  • 전략패턴은 행위와 관련이 있고 브릿지패턴은 구조와 관련이 있음
  • 추가로 전략패턴의 context - strategies 가 브릿지패턴의 abstraction-implementation 보다 강하게 결합함
public interface IBehaviour { public int moveCommand(); } public class AgressiveBehaviour implements IBehaviour{ public int moveCommand() { System.out.println("\tAgressive Behaviour: if find another robot attack it"); return 1; } } public class DefensiveBehaviour implements IBehaviour{ public int moveCommand() { System.out.println("\tDefensive Behaviour: if find another robot run from it"); return -1; } } public class NormalBehaviour implements IBehaviour{ public int moveCommand() { System.out.println("\tNormal Behaviour: if find another robot ignore it"); return 0; } } public class Robot { IBehaviour behaviour; String name; public Robot(String name) { this.name = name; } public void setBehaviour(IBehaviour behaviour) { this.behaviour = behaviour; } public IBehaviour getBehaviour() { return behaviour; } public void move() { System.out.println(this.name + ": Based on current position" + "the behaviour object decide the next move:"); int command = behaviour.moveCommand(); // ... send the command to mechanisms System.out.println("\tThe result returned by behaviour object " + "is sent to the movement mechanisms " + " for the robot '" + this.name + "'"); } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Main { public static void main(String[] args) { Robot r1 = new Robot("Big Robot"); Robot r2 = new Robot("George v.2.1"); Robot r3 = new Robot("R2"); r1.setBehaviour(new AgressiveBehaviour()); r2.setBehaviour(new DefensiveBehaviour()); r3.setBehaviour(new NormalBehaviour()); r1.move(); r2.move(); r3.move(); System.out.println("\r\nNew behaviours: " + "\r\n\t'Big Robot' gets really scared" + "\r\n\t, 'George v.2.1' becomes really mad because" + "it's always attacked by other robots" + "\r\n\t and R2 keeps its calm\r\n"); r1.setBehaviour(new DefensiveBehaviour()); r2.setBehaviour(new AgressiveBehaviour()); r1.move(); r2.move(); r3.move(); } }