JAVA

[JAVA] 디자인패턴 - 전략 패턴(Strategy Pattern)을 알아보자

sagecode 2024. 12. 2. 21:19

1. 전략 패턴(Strategy Pattern)

전략 패턴은 행위패턴에 속하는 패턴이다. 기능은 같지만 다른 전략을 가진 클래스들을 캡슐화하여 서로 교환이 가능하도록 하는 패턴이다. 어떤 목적을 달성하기 위하여 일을 수행하는 방식인 알고리즘을 여기서 전략이라고 한다.

  • 전략 패턴을 왜 사용하는가?

전략 패턴을 사용하면 유지보수가 용이하다. 객체들이 공통으로 할 수 있는 행위들을 캡슐화 하는 인터페이스를 정의하여, 객체의 행위를 동적으로 바꾸고 싶은 경우 직접 각각의 클래스에서 행위를 수정하는 것이 아닌 전략을 바꿔주기만 함으로써 행위를 유연하게 확장할 수 있다.

public interface Moveable {
    public void move();
}

public class Train implements {
    public void move() {
    	System.out.println("철로를 통해 이동");
    }
}

public class Bus implements {
    public void move() {
    	System.out.println("국도를 통해 이동");
    }
}

public class Example {
    public static void main(String[] args) {
    	Moveable train = new Train();
        Movable bus = new Bus();
        
        train.move();
        bus.move();
    }
}

기차는 철로를 통해 이동하고, 버스는 국도를 따라 이동합니다.

그러다가 고속도로가 개발돼서 버스의 경로가 국도에서 고속도로로 바뀌었다고 가정해봅시다.

그렇게 될 경우 Bus 클래스의 move() 메소드를 변경해주면 된다.

public void move() {
    System.out.println("고속도로를 따라 이동");
}

이렇게 수정하게 된다면 버스와 같이 도로로 움직이는 다른 운송수단이 추가된다고 할 때, 모두 버스와 같이 move() 메소드를 각각 수정해야 합니다. 그럴 경우, 같은 메소드를 여러 클래스에서 똑같이 정의하고 있으므로 메소드의 중복이 발생합니다. 이를 해결하고자 전략 패턴을 사용합니다.

  • 전략 패턴 구현

먼저 전략을 생성한다.

현재 운송수단이 철로로 이동하는 방법, 국도로 이동하는 방법, 고속도로로 이동하는 방법 3가지가 존재한다.

이걸 코드로 표현하면 다음과 같다.

public interface MoveStrategy {
    public void move();
}

public class RailroadStrategy implements MoveStrategy {
    public void move() {
    	System.out.println("철로를 통해 이동");
    }
}

public class NationalroadStrategy implements MoveStrategy {
    public void move() {
    	System.out.println("국도를 통해 이동");
    }
}

public class HighwayStrategy implements MoveStrategy {
    public void move() {
    	System.out.println("고속도로를 통해 이동");
    }
}

 

그 다음 운송 수단에 대한 클래스를 정의한다.

운송수단들은 move() 메소드에 의해서 움직인다.

또한, 어떤 전략을 통해서 움직일지에 대한 메소드인 setMoveableStrategy() 를 선언한다.

public class Transport {
    private MoveableStrategy moveablestrategy;
    
    public void move() {
    	moveableStrategy.move();
    }
    
    public void setMoveableStrategy(MoveableStrategy moveablestrategy)
        this.moveableStrategy = moveableStrategy;
    }
}

 

이제 각 운송수단을 이용하는 Client를 구현해보자. 

public class Client {
    public static void main(String[] args) {
        Transport train = new Train();
        Transport bus = new Bus();
        
        train.setMoveableStrategy(new RailroadStrategy);
        bus.setMoveableStrategy(new NationalroadStrategy);
        
        train.move();
        bus.move();
        
        // 버스가 국도에서 고속도로 다니는 전략이 변경됨
        
        bus.setMoveableStrategy(new HighwayStrategy);
        bus.move();
    }
}

출력 결과는

철로를 통해 이동
국도를 통해 이동
고속도로를 통해 이동

이런식으로 전략 패턴을 사용하면 각 메소드를 직접 수정하지 않아도 유지보수하기에 편리하다.