전략 패턴 (Strategy Pattern)

반응형
728x90
반응형
수강완료한 강의 복습해보자
(코딩으로 학습하는 GoF의 디자인 패턴)



전략 패턴 (Strategy Pattern)

  • 여러 알고리즘을 캡슐화하고 상호 교환 가능하게 만드는 패턴.
  • 사용할 알고리즘을 클라이언트가 선택한다.

 

 

적용 전 코드 (Before)

BlueLightRedLight.java
public class BlueLightRedLight {

    private int speed;

    public BlueLightRedLight(int speed) {
        this.speed = speed;
    }

    public void blueLight() {
        if (speed == 1) {
            System.out.println("무 궁 화    꽃   이");
        } else if (speed == 2) {
            System.out.println("무궁화꽃이");
        } else {
            System.out.println("무광꼬치");
        }

    }

    public void redLight() {
        if (speed == 1) {
            System.out.println("피 었 습 니  다.");
        } else if (speed == 2) {
            System.out.println("피었습니다.");
        } else {
            System.out.println("피어씀다");
        }
    }
}

 

Client.java
public class Client {
    public static void main(String[] args) {
        BlueLightRedLight blueLightRedLight = new BlueLightRedLight(3);
        blueLightRedLight.blueLight();
        blueLightRedLight.redLight();
    }
}

 

1) 요구사항

BluLight, RedLight은 speed 1, 2, 3에 따라서 다르게 결과값을 출력한다.

 

2) 문제점

speed 에 따라 if~else 문으로 분기 처리되어있다.

이렇게되면 speed 가 다른 값이 추가되거나 또는 speed 외의 다른 요소가 추가된다면 코드 수정이 많이 발생하고, 버그 발생율이 높아진다.

    public void blueLight() {
        if (speed == 1) {
            System.out.println("무 궁 화    꽃   이");
        } else if (speed == 2) {
            System.out.println("무궁화꽃이");
        } else {
            System.out.println("무광꼬치");
        }

    }

    public void redLight() {
        if (speed == 1) {
            System.out.println("피 었 습 니  다.");
        } else if (speed == 2) {
            System.out.println("피었습니다.");
        } else {
            System.out.println("피어씀다");
        }
    }

 

3) 추가요건

speed 에 0을 추가하여 공백을 출력하는 로직을 추가해라.

단지 speed 조건이 0으로 1개 추가했을 뿐인데, BlueLightRedLight 에 추가로 else if문을 작성해야한다.

요건이 추가될때마다 계속 이렇게 추가해야할까?

 

 

 

적용 후 코드 (After)

Speed.java
public interface Speed {
    void blueLight();
    void redLight();
}

 

Normal.java
public class Normal implements Speed {
    @Override
    public void blueLight() {
        System.out.println("무 궁 화    꽃   이");
    }

    @Override
    public void redLight() {
        System.out.println("피 었 습 니  다.");
    }
}

 

Faster.java
public class Faster implements Speed {
    @Override
    public void blueLight() {
        System.out.println("무궁화꽃이");
    }

    @Override
    public void redLight() {
        System.out.println("피었습니다.");
    }
}

 

Fastest.java
public class Fastest implements Speed{
    @Override
    public void blueLight() {
        System.out.println("무광꼬치");
    }

    @Override
    public void redLight() {
        System.out.println("피어씀다.");
    }
}

 

BlueLightRedLight.java
public class BlueLightRedLight {

    // 호출 시점에 파라미터로 전략을 넘긴다.
    public void blueLight(Speed speed) {
        speed.blueLight(); // 작업 위임 (이 파일이 변경되도 전략에는 영향이 없다)
    }

    public void redLight(Speed speed) {
        speed.redLight();
    }
}

 

Client.java
public class Client {
    public static void main(String[] args) {
        BlueLightRedLight game = new BlueLightRedLight();

        // 새로운 전략은 클래스 추가 필요 (기존 클래스(BlueLightRedLight)의 수정은 필요 없다)
        game.blueLight(new Normal());
        game.redLight(new Fastest());

        game.blueLight(new Speed() {
            @Override
            public void blueLight() {
                System.out.println("blue light");
            }

            @Override
            public void redLight() {
                System.out.println("red light");
            }
        });
    }
}

 

 

위 Before 에서 봤던 추가 요건을 다시 생각해보자.

1) 추가요건

[추가요건]
peed 에 0을 추가하여 공백을 출력하는 로직을 추가해라.

 

2) 추가요건

[추가요건]
speed 에 0을 추가하여 공백을 출력하는 로직을 추가해라.

 

Stop 클래스를 추가하고, client 에서 호출하면 된다.

Speed 라는 전략을 인터페이스로 둠으로써, 추가되는 구체 전략들은 해당 인터페이스를 구현하는 구현 클래스로 추가된다. 여기서 중요한점은, 기존에 구현되어있던 코드들은 수정되지 않았다는 것이다.

public class Stop implements Speed{
    @Override
    public void blueLight() {
        System.out.println(" ");
    }

    @Override
    public void redLight() {
        System.out.println(" ");
    }
}

...

// client 호출
game.blueLight(new Stop());

 

 

적용 결과

장점
  • 새로운 전략을 추가하더라도 기존 코드를 변경하지 않는다.

 

단점
  • 클라이언트 코드가 구체적인 전략을 알아야한다.
  • 어떤 전략들이 존재하는지를 클라이언트가 알고있어야하며, 본인이 원하는 전략을 선택해야한다.

 

 

 

github : https://github.com/seohaem/java/tree/master/java_GoFdesignpattern

강의 : https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4

 

 

 

반응형

Designed by JB FACTORY