콘텐츠로 이동

2021 03 13

2021-03-13

전략 패턴

  • 전략 패턴은 실행 중에 알고리즘을 선택할 수 있게 하는 디자인 패턴
  • 전략 패턴은 런타임에 전략을 선택할 수 있게 하는 디자인 패턴 - 특정한 계열의 알고리즘(전략)들을 정의하고 - 각 알고리즘(전략)들을 캡슐화하여 - 이 알고리즘들을 해당 계열 안에서 상호 교체가 가능토록 한다
  • 전략 패턴을 이루는 구성 요소는... - 전략 (strategy) : 변하는 것으로, 구체화된 여러가지 알고리즘들의 추상화 - 전략 콘트리트 클래스: 여러가지 알고리즘의 실제 구현 - 전략 사용자 (context) : 전략을 사용하는 프로그램의 흐름으로, 변하지 않는 것 - 전략 제공자 (client) : 전략 사용자에게 실제 전략으로 사용할 전략 콘크리트 클래스를 주입하는 역할
  • 전략 객체(strategy)는 전략 사용자(context)를 사용하는 전략 제공자(client)에서 직접 생성
  • 코드 예시
        // 전략 제공자 (client): 전략 사용자에게 실제 셔플 전략 주입
        public void run() {
            final CardDeck cardDeck = CardDeckFactory.make(new RandomShuffleStrategy());
        }
    
        // 전략 사용자 (context): 전략을 사용하는 실제 프로그램의 흐름으로, 변하지 않음.
        // 해당 에시에서는 cards를 셔플한 후, 새로운 CardDeck 객체를 만드는 흐름이 변하지 않는다. 
        public static CardDeck make(ShuffleStrategy shuffleStrategy) {
            return new CardDeck(shuffleStrategy.shuffle(cards));
        }
    
        // 전략: 셔플을 하는 전략에 대한 추상화 
        public interface ShuffleStrategy {
            List<Card> shuffle(final List<Card> cards);
        }
    
        // 전략 콘크리트 클래스: 실제 카드 셔플 전략
        public class RandomShuffleStrategy implements ShuffleStrategy {
            @Override
            public List<Card> shuffle(final List<Card> cards) {
                Collections.shuffle(cards);
                return cards;
            }
        }
    
  • 전략 패턴의 장점 - context 코드의 변경없이 새로운 전략을 추가할 수 있음 - 이를 통해 if-else의 분기를 없앨 수 있다 - OCP의 원칙을 준수한 구조 개선이 가능하다 - 확장에 유리한 코드를 작성할 수 있다 - 런타임에 전략을 변경시킬 수 있다
  • 전략 패턴의 단점 - 어플리케이션이 모든 전략에 대해 알고있어야 한다 - 클래스로 분리한 각 전략들이 어디에 사용되어야 할지 알아야하니, 어쩌면 유지보수가 어려워진다고 말할 수 있겠다 - 전략 패턴에서는 주로 전략 제공자에게 전략을 인터페이스로 주입하게 된다. - 어떤 전략 콘크리트 객체에서는 사용하지 않는 메서드들 역시 인터페이스에 작성해둬야함.

상태 패턴

  • 의도 - 객체 자신의 내부 상태에 따라 수행해야 하는 행위를 변경하는 효과를 주기 위해서
  • 활용 - 객체의 행위는 상태에 따라 달라진다 - 객체의 상태에 따라서 프로그램 실행 중에 수행해야 하는 행위를 변경할 때 활용하자 - 객체의 상태에 따라 수 많은 if를 사용해야 할 때, 이를 피할 수 있는 방법 중에 하나!
  • 정의 - 기능이 "상태"에 따라서 다르게 동작해야 할 때 사용하는 패턴! - "상태" 객체가 "기능"을 제공한다!