Devxplorer – 세상을 분석하는 개발자의 탐험기

IT, 경제, 인물, 건강 – All Explored

Devxplorere 자세히보기

IT (IT)🤖🧠/Design Pattern

[Design Pattern ] 1. Strategy Pattern Purpose & Use

데브엑스플로러 2024. 3. 11. 22:38
728x90
반응형

Strategy Pattern (전략패턴) 의 목적은 여러 알고리즘을 사용자에게 Encapsulation 하기 위한 것이다. 같은 Interface를 사용하지만, 서로 다른 알고리즘을 제공하여, 사용자는 이를 전략적으로 변경하여 사용할 수 있다. 전략패턴은 소프트웨어 디자인 패턴 중 하나로, 특정한 작업이나 알고리즘을 실행하는 방법을 동적으로 선택하고 변경할 수 있도록 하는 패턴이다. 이 패턴은 알고리즘이나 동작의 다양한 변형이 필요한 상황에서 유용하고, 코드의 재사용성과 확장성을 향상하는데 도움을 준다.

Component

  • Strategy Interface : 실행할 알고리즘 또는 동작을 정의하는 인터페이스이다. 다양한 전략은 이 인터페이스를 구현하여 특정 작업을 수행한다.
  • Concrete Stratagies : 전략 인터페이스를 구현한 클래스로, 서로 다른 알고리즘 또는 동작을 구현한다. 각 구체적인 전략은 고유한 동작을 수행한다.
  • Context : Context는 전략을 사용하는 클라이언트 코드를 가르킨다. Context는 전략 interface를 가지며, 실행 시에 특정 전략 객체를 설정하고, 이를 사용하여 작업을 수행 한다.

When Use Strategy Pattern

Strategy Pattern 을 사용하는 경우

  • 관련된 클래스의 Interface는 동일하지만 유일한 차이점이 구체적인 행동일 때,
  • 한 알고리즘에 대한 버전이나 변경이 어러 개일때,
  • 알고리즘이 사용하는 데이터를 호출하는 코드와 분리 시키고자 할 때,
  • 한 클래스의 행동이 런타임시에 결정되어야 할 때,
  • 조건문이 복잡하고 관리하기 힘들 때,

Consideration

전략 패턴은 많은 경우에 유용하지만, 몇 가지 단점과 고려해야 할 사항이 있다.

  1. 복잡성 증가: 전략 패턴을 도입하면 코드 기반에 추가적인 클래스 및 인터페이스가 필요하며, 전략들과 컨텍스트 간의 상호작용을 관리하기 위한 코드가 늘어날 수 있다. 이로 인해 코드의 복잡성이 증가할 수 있다.
  2. 객체 생성 오버헤드: 전략 패턴은 많은 전략 객체를 생성해야 할 때, 객체 생성에 따른 오버헤드가 발생할 수 있다. 이를 해결하기 위해서는 객체 풀링과 같은 기술을 사용할 수 있다.
  3. 전략 선택 오버헤드: 컨텍스트에서 실행할 전략을 선택하는 데 추가적인 로직이 필요할 수 있다. 이로 인해 코드 실행 속도에 영향을 줄 수 있으며, 선택 로직을 최적화해야 한다.
  4. 과도한 분리: 과도한 분리로 인해 코드가 지나치게 분산될 수 있으며, 작은 규모의 애플리케이션에서는 오히려 불필요한 복잡성을 초래할 수 있다.
  5. 과용: 모든 상황에 대해 전략 패턴을 적용하는 것은 비효율적일 수 있다. 간단한 알고리즘을 변경할 필요가 없는 경우에도 전략 패턴을 도입하면 코드를 더 복잡하게 만들 수 있다.
  6. 선택 오류: 컨텍스트에서 전략을 선택하는 과정에서 오류가 발생할 수 있다. 예를 들어, 올바른 전략을 설정하지 않는 실수가 발생할 수 있다.
  7. 메모리 사용: 많은 전략 객체를 생성하고 보관해야 할 때, 메모리 사용량이 증가할 수 있으며, 이를 관리해야 한다.

전략 패턴을 사용할 때는 특히 코드의 유지보수성과 확장성을 고려하면서 사용해야 한다. 필요한 상황에서 적절하게 적용하는 것이 중요하며, 너무 복잡한 구조를 만들지 않도록 주의해야 한다.

Example

가장 많이 사용하는 Duck 예시이다. 세상에는 여러 종류의 오리가 있다. 오리마다 Fly에 대한 행위가 다를 수도 있고, Quack 에 대한 행위가 다를 수 있다. 따라서 추상적이고 일반화된 Interface를 정의하고, 이를 상속 받아 각각의 Concrete 한 Duck들은 자신에 맞게 구현한다.

Client는 이러한 Interface들을 Composite 하여 선언한다. Interface를 갖고 이를 통해 오리 종류에 따라 각자에 맞는 동작 들을 Runtime에 선택할 수 있다. Client는 Interface를 통해서만 알고, 구체적인 동작은 숨겨져 있다.

또 다른 예제로 Sorting에 대한 동작을 Runtime에 변경할 때 하기와 같이 사용할 수 있다. Sort를 서로 다르게 각각의 클래스에서 구현하고 이를 Interface를 제공한다. 이 Interface를 SortedList에서 composit 한다. 어떤 Sort를 사용할지 정책을 Main에서 정하고, 이를 통해 선택된 Sort가 호출 된다.

Summary

전략 패턴은 Inheritance 가 아닌 Composition 을 통해 알고리즘을 Runtime에 변경한다. Composition 을 사용함으로써 확장성과 유지보수성을 높였다. RunTime에 알고리즘의 변경을 가능하게 하는 Pattern이다. Is-a 관계를 사용하지 않고 Has-a 관계를 사용하여 확장성을 고려한다.

전략 패턴은 다음의 장점을 갖는다.

  1. 코드의 재사용성 : 전략 패턴을 사용하면 각각의 전략을 독립적으로 개발하고 테스트 할 수 있으므로 코드 재사용성이 높아진다.
  2. 확장성 : 새로운 전략을 추가하거나 기존 전략을 변경하는 것이 비교적 쉽다. 이로써 시스템의 알고리즘 확장을 유용하게 한다.
  3. 유지보수성 : 전략 패턴은 코드를 더 이해하기 쉽게 만들어 주며, 수정 및 유지보수를 용이하게 한다.
  4. 런타임 선택 : Context에서 사용할 전략을 런타임에 동적으로 선택할 수 있으므로, 다양한 동작을 동적으로 변경할 수 있다.

전략패턴은 다양한 분야에서 사용된다. 정렬 알고리즘, 게임 캐릭터 공격 전략 선택 등 다양한 상황에서 유용하게 적용된다. 이 패턴을 사용하면 시스템을 보다 유연하게 만들고, 변경에 대한 영향을 최소화할 수 있다.

반응형