CS/객체지향설계 & 패턴

[객체지향설계 & 패턴] 전략 패턴

hyeon0117 2025. 5. 21. 17:38

개요

 내비게이션 안내 앱을 서비스하기 위해 사용자가 목적지까지 자동차로 도로를 이동하는 경우만 고려하여 앱을 서비스하였다. 좋은 반응을 얻어 자동차를 이용하는 경우 이외에도 자전거를 이용한 경우, 도보를 이용한 내비게이션 안내 서비스를 추가하려고 한다. 그런데, 자전거와 도보를 이용하는 case를 모두 앱에 집어넣다 보니 클래스의 크기가 너무 커져버렸다. 이용자들은 주변 랜드마크를 경유하여 목적지까지 이동하는 등의 여러 경우를 추가로 서비스 해달라고 하는데, 개발자들은 너무 커진 클래스의 크기에 당황하며 서비스 추가에 어려움을 겪고 있다. 이런 경우에 전략 패턴을 이용하여 리팩토링해야 한다.

 

 프로그램은 문제를 해결하기 위해 만들어지고, 문제를 풀기 위해서는 알고리즘을 만들어야 한다. 이 전략 패턴에서는 구현한 알고리즘을 스위치를 바꾸듯 알고리즘을 바꿔 같은 문제를 다른 방법으로 해결하기 쉽게 만들어 준다. 위 경우에서는 자동차가 도로를 이용하는 알고리즘, 도보를 이용하는 알고리즘, 자전거를 이용하는 알고리즘 등을 스위칭하는 방식으로 앱을 서비스하면 될 것이다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public interface MoveStrategy {
    void move();
}
 
public class WalkStrategy implements MoveStrategy {
    public void move() {
        // 지면을 걸어 이동하는 로봇 알고리즘 작동 중..
        System.out.println("걷습니다.");
    }
}
 
 
public class FlyStrategy implements MoveStrategy {
    public void move() {
        // 하늘을 날아 이동하는 로봇 알고리즘 작동 중...
        System.out.println("하늘을 납니다!");
    }
}
 
 
public class RunStrategy implements MoveStrategy {
    public void move() {
        // 지면을 달려 이동하는 로봇 알고리즘 작동 중..
        System.out.println("달립니다!");
    }
}
 
 
public class Robot {
    private MoveStrategy strategy;
 
    public void setMoveStrategy(MoveStrategy strategy) {
        this.strategy = strategy;
    }
 
    public void move() {
        strategy.move();
    }
}
cs

 

 개요에서 언급한 것과는 다르지만, 로봇이 이동하는 경우를 생각해 보자. Move는 로봇의 이동 전략이며, Walk, Fly, Run은 구체적인 로봇의 이동 전략이다. API가 정의된 Strategy 전략 인터페이스를 구체적인 전략 Walk, Fly, Run이 구현하고 있다. 구현된 이동 전략 strategy는 Robot 클래스가 이것을 이용하여 이동하고 있다. Robot의 setMoveStrategy 메소드를 통해 이동 전략만 변경하면 해당 이동 전략 Walk, Fly, Run 중 하나에 해당하는 방식으로 움직일 것이다.

 

만약, 위 전략 패턴이 적용되지 않았을 때를 생각해보자. 로봇이 먼저 Walk로 움직이고 있는데, 하늘을 날아 이동해야 하는 경우도 고려하여 적절한 위치에서 Fly를 호출해야 할 것이며, 빠르게 이동해야 하는 곳에서는 Run을 호출해 움직여야 할 것이다. 이런 번거로움을 전략 패턴으로 없애 이동 전략만 교체하여 프로그램을 더 쉽게 설계할 수 있을 것이다. 

 

마무리

 전략 패턴을 이용하였을 때의 장점은 OCP를 잘 지킬 수 있는 것인데, 이것 이외에도 강력한 장점이 있다. 바로 런타임에 필요한 전략을 전환할 수 있는 것이다. 프로그램을 돌리는데 메모리가 적은 환경에서는 속도는 느리지만 메모리를 절약하는 전략을 사용할 수 있고, 메모리가 많으면 속도는 빠르지만 메모리를 더 많이 쓰는 전략을 사용할 수 있을 것이다.