티스토리 뷰

전략 패턴이란 같은 기능이지만, 서로 다른 전략을 가진 클래스들을 캡슐화하여 상호 교환할 수 있도록 도와주는 디자인 패턴입니다.

 

전략 패턴 예시

현재 시스템은 VIP 회원에 대한 2,000원 할인을 해주는 정책을 기본적으로 제공하고 있으며, 상황에 따라 새로운 정책이 추가될 가능성이 높은 상황입니다. 아래의 코드를 보면서 전략 패턴을 설명하도록 하겠습니다.

회원 등급을 가지고 있는 Member 클래스
public class Member {

    private final Long id;
    private final String name;
    private final Grade grade;
    
    public enum Grade { BASIC, VIP }

    public Member(Long id, String name) {
        this.id = id;
        this.name = name;
        this.grade = Grade.BASIC;
    }
    
    void setGrade(Grade grade) {
        this.grade = grade;
    }
    
    Grade getGrade() {
        return grade;
    }
}
DiscountPolicy 인터페이스를 통해 할인 금액 조회 기능을 제공한다.
public interface DiscountPolicy {
    int getDiscountPrice(Member member, int price);
}
DiscountPolicy 인터페이스를 구현한 FixedDiscountPolicy 클래스
public class FixedDiscountPolicy implements DiscountPolicy {

    @Override
    public int getDiscountPrice(Member member, int price) {
        if (member.getGrade() == Member.Grade.VIP) return 2_000;
        return 0;
    }
}
DiscountService 클래스를 통해 할인 정보를 반환한다.
public class DiscountService {

    private final MemberFinder memberFinder;
    
    public DiscountService(MemberFinder memberFinder) {
        this.memberFinder = memberFinder;
    }

    public int getDiscountPrice(Long memberId, int price, DiscountPolicy discountPolicy) {
        Member member = memberFinder.findById(memberId);
        // 할인 정보를 반환
        return discountPolicy.getDiscountPrice(member, price);
    }
}
Client는 VIP 등급에 따라 할인을 받을 수 있는지 정보를 조회할 수 있다.
public class Client {

    public static void main(String[] args) {
        // 할인 정보 조회
        Long memberId = 1;
        int price = 10_000;
        discountPolicy.getDiscountPrice(memberId, price, new FixedDiscountPolicy());
    }
}

시간이 지나 VIP 등급에 대한 할인 정책이 비율 할인으로 변경되었고, 기존의 FixedDiscountPolicy는 더 이상 사용하지 않게 되었습니다. Client는 새롭게 추가되는 정책에 따라 변경된 할인 금액을 조회해야 하는 상황이 오게 되었는데, 전략 패턴을 사용하게 되면 전체적인 구조에서 큰 변화 없이 유지 보수가 가능하게 됩니다.

새롭게 추가된 RateDiscountPolicy
public class RateDiscountPolicy implements DiscountPolicy {

    private final int discountPercent = 10;

    @Override
    public int discount(Member member, int price) {
        if (member.getGrade() == Member.Grade.VIP) {
            return price * discountPercent / 100;
        }
        return 0;
    }
}
Client는 RateDiscountPolicy로 변경하면 된다.
public class Client {

    public static void main(String[] args) {
        // 할인 정보 조회
        Long memberId = 1;
        int price = 10_000;
        // RateDiscountPolicy로 변경
        discountPolicy.getDiscountPrice(memberId, price, new RateDiscountPolicy());
    }
}
변경된 부분이 없는 DiscountService
public class DiscountService {

    private final MemberFinder memberFinder;
    
    public DiscountService(MemberFinder memberFinder) {
        this.memberFinder = memberFinder;
    }

    public int getDiscountPrice(Long memberId, int price, DiscountPolicy discountPolicy) {
        Member member = memberFinder.findById(memberId);
        // 할인 정보를 반환
        return discountPolicy.getDiscountPrice(member, price);
    }
}

RateDiscountPolicy로 변경됐지만, DiscountService에서는 추가된 할인 정책과 상관없이 할인 금액 조회 기능을 정상적으로 수행하고 있으며, 로직을 수정할 필요도 없습니다. Client에서는 그저 RateDiscountPolicy를 사용하기만 하면 됩니다.

 

정리

위와 같은 예시를 통해 '할인 금액을 조회한다.'라는 공통 기능이 있지만, 상황에 따라 다른 전략인 FixedDiscountPolicy, RateDiscountPolicy가 상호 교환되는 부분을 확인할 수 있으며, 전략 패턴은 유지 보수하는 과정에서 변경을 최소화할 수 있는 장점을 가지고 있습니다.

 

참고

https://jackjeong.tistory.com/108

 

[Java] Strategy Pattern(전략패턴)[feat. Interface]

안녕하세요~ 잭코딩입니다! 이번에는 인터페이스의 활용에 대해 글을 써보려고 합니다! 요즘 글쓴이는 우아한테크캠프 Pro라는 교육과정을 듣고 있습니다 이번 미션에서 Strategy Pattern을 적용해

jackjeong.tistory.com

https://johngrib.github.io/wiki/strategy-pattern/

 

전략 패턴(strategy pattern)

동일 계열의 알고리즘을 정의하고 상호교환이 가능하게 한다

johngrib.github.io

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

템플릿 메서드 패턴 (Template Method Pattern)  (0) 2022.04.28
어댑터 패턴 (Adapter Pattern)  (0) 2021.09.14
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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
글 보관함