CS/디자인 패턴

[디자인 패턴] 전략(Strategy) 패턴이란?

jyp-on 2023. 11. 28. 15:04

전략 패턴(strategy pattern) 또는 정책 패턴(policy pattern)은 실행 중에 알고리즘을 선택할 수 있게 하는 소프트웨어 디자인 패턴이다. 

 

전략패턴은 다음과 같은 이점이 있다.

  • 비슷한 동작을 하지만 다르게 구현되어 있는 행위(전략)들을 공통의 인터페이스를 구현하는 각각의 클래스로 구현하고, 동적으로 바꿀 수 있게 함
  • 직접 행위에 대한 코드를 수정할 필요 없이 전략만 변경하여 유연하게 확장

전략패턴 UML

 

1. 공통의 기능을 명시한 인터페이스를 생성한다.

2. 기능에 맞게 1번의 구현 클래스들을 생성한다.

3. Context 클래스 생성 및 인터페이스를 저장하는 메소드와 인터페이스의 메소드를 실행하는 메소드를 생성한다.

 

예제의 Diagram By Intellij

 

위의 UML을 보고 간단한 결제 시스템 예제를 통해 코드를 이해해보자.

interface Pay {
    void card(int m);
}

class KakaoPay implements Pay {

    @Override
    public void card(int m) {
        System.out.println("Kakao pay 결제금액 : " + m + "원");
    }
}

class NaverPay implements Pay {

    @Override
    public void card(int m) {
        System.out.println("Naver pay 결제금액 : " + m + "원");
    }
}

 

1번에 해당하는 Pay 인터페이스를 작성한다.

 

2번에 해당하는 KaKaoPay, NaverPay, SamsungPay 클래스들을 생성후 Pay 인터페이스를 구현하여 card 메소드에 대한 구체적인 메소드를 작성해준다.

 

3번에 해당하는 Context클래스를 Payment라는 이름으로 생성해준다.

여기서 Pay 인터페이스를 인스턴스 멤버로 가지고 이를 변경해주는 메소드와 pay.card를 실행해주는 메소드를 만들어 준다.

 

이곳이 전략패턴의 핵심부분이다. 

class Payment {
    private Pay pay;

    public void setPayCompany(Pay p) {
        this.pay = p;
    }

    public void onlinePay(int m) {
        pay.card(m);
    }
}

 

새로운 기능이 추가된다면 Pay를 구현한 클래스를 하나 만들고 card 메소드를 자신이 원하는 기능으로만 바꿔준다면 Payment에서 setPayCompany 를 통해 변경만 해준다면 코드를 쉽게 변경 가능하다.

이것이 가능한 이유는 Payment 클래스의 인스턴스 변수가 Pay를 구현한 각각의 클래스가 아니라 Pay 인터페이스이기 때문이다. 

 

Java의 인터페이스는 변수로 사용가능하며 자신을 구현한 하위 객체들은 인터페이스의 메소드를 반드시 같이 구현해야 하기 때문에 컴파일러에게 Pay라고 속일 수 있다. 컴파일러는 Pay 인터페이스를 바라보지만 실제로 실행이 된다면 실제 구현한 클래스를 찾아가기 때문에 이러한 방식이 가능하다.

 

메인문을 살펴보자.

public class StrategyPatternEx {

    public static void main(String[] args) {
        int money = 10000;
        Payment pm = new Payment();

        pm.setPayCompany(new KakaoPay());
        pm.onlinePay(money);
    }
}

 

Context 클래스인 Payment 객체를 생성 후 setPayCompany를 통해 인터페이스를 구현한 KakaoPay클래스를 넣어준다.

Payment의 pay변수는 KaoaoPay를 가르킨다. 

 

pm.onlinePay(money) 를 호출하면 다음과 같은 결과를 볼 수 있다.

Kakao pay 결제금액 : 10000원

 

만약 여기서 NaverPay로 바꾸고 싶다면 구현체만 바꿔주면 된다. 

money를 20000원으로 바꾸고 NaverPay로 결제 하는 코드다.

public class StrategyPatternEx {

    public static void main(String[] args) {
        int money = 10000;
        Payment pm = new Payment();

        pm.setPayCompany(new KakaoPay());
        pm.onlinePay(money);

        money = 20000;
        pm.setPayCompany(new NaverPay());
        pm.onlinePay(money);
    }

}

 

다음과 같이 잘 바뀐 것을 확인할 수 있다.

Kakao pay 결제금액 : 10000원
Naver pay 결제금액 : 20000원

 

위와 같이 직접 행위에 대한 코드를 수정할 필요 없이 전략만 변경하는 패턴을 전략 패턴 이라고 한다.

'CS > 디자인 패턴' 카테고리의 다른 글

[디자인 패턴] 싱글턴 패턴이란?  (0) 2023.11.27
[디자인 패턴] 디자인 패턴이란?  (0) 2023.11.27