🌈디자인패턴

[Design Pattern] 스트레티지 패턴 (Strategy Pattern)

창히 2022. 7. 26. 01:38

❓스트레티지 패턴(Strategy Pattern) 이란

여러 알고리즘을 하나의 추상적인 접근점을 만들어 접근점에서 상호교환 가능하도록 하는 패턴으로
유연하고 재사용 가능한 OOP 설계를 위해 반복되는 디자인 문제를 해결 하는 방법론

 

카페에서 작성하다 문득 든 간단한 예시로 내가 세워볼 전략은 커피머신에서 다양한 커피를 내리는 것!

 

❗️요구사항

커피머신에서 다양한 커피를 내릴 수 있도록 구현
(추후에 커피의 종류가 추가 될 수도 있음)

커피의 종류
1. 아메리카노
2. 카페라떼
3. 콜드브루

 

⚙️ Class Diagram

Class Diagram

 

Class Diagram 설명을 하자면 execute에서 실행이 되며 CoffeeMachine 객체에 Coffee 라는 추상적인 접근점을 통해 다양한 Coffee를  선택(교체)(setCoffee)하고 Coffee를 내리는(brew) 과정이다.

 

1. 추상적인 접근점인 커피 인터페이스를 생성해주고(추상화) 커피를 내리는 것[brew()]을 정의해준다.

public interface Coffee {
    void brew();
}

 

2. 다양한 커피들을 구현해주고 brew를 오버라이딩(다형성) 하여 서로다른 알고리즘을 구현해준다.

(간단한 예제여서 알고리즘이라고 하기에는 다소 부족하지만 출력문구를 달리하여 서로 다른 알고리즘이 구현될 수 있다는 뜻❗️)

public class Americano implements Coffee {
    @Override
    public void brew() {
        System.out.println("아메리카노를 내리고 있습니다.");
    }
}

public class CafeLatte implements Coffee {
    @Override
    public void brew() {
        System.out.println("카페라떼를 내리고 있습니다.");
    }
}

public class ColdBrew implements Coffee{
    @Override
    public void brew() {
        System.out.println("콜드브루를 내리고 있습니다.");
    }
}

 

 

 

3. CoffeMachine에서 Coffe라는 접근접(캡슐화)을 두어 setCoffee를 통해 커피가 선택(교환)이 가능하도록 하며

커피머신에서 커피를 내릴 때 커피가 선택이 되지 않았을 경우와 선택이 됐을 경우 구분

선택이 됐을 경우는 선택된 커피를 위임받아 실제 아메리카노면 아메리카노를 내리는 로직이 실행되도록함. 

public class CoffeeMachine {

    //접근점
    private Coffee coffee;

    //커피 선택(교환 가능)
    public void setCoffee(Coffee coffee) {
        this.coffee = coffee;
    }

    //커피 내리기
    public void brew() {
        if (coffee == null) {
            System.out.println("커피의 종류가 선택되지 않았습니다.");
        } else {
            //위임
            this.coffee.brew();
        }
    }
}

 

4. 실행

public class execute {

    public static void main(String[] args) {

        //커피 머신 객체를 생성해준다.
        CoffeeMachine coffeeMachine = new CoffeeMachine();

        //1. 커피 종류 미선택 후 커피를 내릴 경우
        coffeeMachine.brew();

        //2. 커피 종류를 아메리카노로 선택하고 커피를 내린다.
        coffeeMachine.setCoffee(new Americano());
        coffeeMachine.brew();

        //3. 커피 종류를 카페라떼를 선택하고 커피를 내린다.
        coffeeMachine.setCoffee(new CafeLatte());
        coffeeMachine.brew();

        //4. 커피 종류를 콜드브루를 선택하고 커피를 내린다.
        coffeeMachine.setCoffee(new Coldbrew());
        coffeeMachine.brew();
    }
}

/* 실행결과 */
커피의 종류가 선택되지 않았습니다.
아메리카노를 내리고 있습니다.
카페라떼를 내리고 있습니다.
콜드브루를 내리고 있습니다.

 

💡 생각정리

위 예제는 알고리즘이랄 게 없이 단순한 이해 목적으로 출력형태로 만들어졌지만
실제로 전략패턴이 저렇게 단순하게 사용되지는 않는다.

Ex)
1. 상품의 할인율을 유저의 레벨별로 정책을 세울 수 있다.
2. OAuth 인증에서 플랫폼 별 인증 provider를 생성할 수 있다.

인터페이스 추상메소드가 각 전략 서브클래스에 공유되기 때문에 쓰이지 않는 메소드까지 서브클래스에서 떠안아야 한다. 이와 같은 상황이 생기지 않기 위해서는 꼭 공통 전략으로 필요한 부분만 간소화 하는 것이 좋아보인다.

전략이 많아지면 많아질수록 프로그램 수가 증가되며 관리 포인트가 방대해진다.

전략을 가지지 않을 때는 공통적으로 기본 알고리즘 수행이 가능하다.

 

 

📝참고

 

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

 

학습 페이지

 

www.inflearn.com

 

반응형