본문 바로가기
안드로이드 프로그래밍/design pattern

[kotlin] Strategy Pattern 이란

by 1chanhue1 2024. 7. 16.

Strategy Pattern 이란 ? 

  • 정책 패턴(Policy Pattern) 이라고도 불린다. 
  • 알고리즘군을 정의하고 캡슐화해서 각각의 알고리즘군을 수정해서 사용할 수 있게 해줌
  • 객체의 행위를 변경하고 싶은 경우 직접 수정하지 않고 전략이라 불리는 캡슐화한 알고리즘을 변경해줌으로써 유연하게 확장하는 방법

정리하자면 ! !  인터페이스를 사용해 기본 행위를 정의한 후 객체의 행위를 변경하고싶을 때, 직접적으로 행위를 수정하는 것이 아닌, 객체에서만 행위를 변경해 유연하게 확장하는 패턴

그렇다면 언제 사용할까 ? 

 

Strategy 패턴을 사용하는 상황은 다양한 알고리즘이 필요하고, 이들 알고리즘을 유연하게 교체하거나 확장할 수 있는 구조가 필요할 때입니다. 다음은 Strategy 패턴을 사용할 만한 몇 가지 예시이다. 

데이터 정렬 알고리즘

애플리케이션에서 데이터를 정렬하는 방법이 여러 가지 있고, 상황에 따라 다른 정렬 알고리즘을 사용하고 싶을 때 사용합니다. 예를 들어, 데이터의 크기에 따라 선택 정렬, 병합 정렬, 퀵 정렬 등 다양한 정렬 알고리즘을 선택할 수 있습니다.

결제 처리 시스템

전자상거래 애플리케이션에서 결제 방법을 다르게 처리해야 할 때 사용합니다. 예를 들어, 신용카드, 페이팔, 애플 페이 등 다양한 결제 방법이 있을 수 있습니다.

텍스트 변환기

텍스트를 변환하는 방법이 여러 가지 있고, 상황에 따라 다른 변환기를 사용하고 싶을 때 사용합니다. 예를 들어, 텍스트를 대문자로 변환하거나 소문자로 변환하거나, 각 단어의 첫 글자만 대문자로 변환하는 등의 변환기가 있을 수 있습니다.

+.. 상황에 따라 길찾기 알고리즘을 바꾸고 싶을 때 , 게임 룰을 모드 별로 다르게 적용하고 싶을 떄 

장점

  • OCP (개방-폐쇄 원칙) , 개방-폐쇄 원칙(Open/Closed Principle)은 소프트웨어 구성 요소(클래스, 모듈, 함수 등)가 확장에는 열려있고 수정에는 닫혀있어야 한다는 원칙이다. Strategy 패턴은 이 원칙을 잘 준수한다. 예를 들어, 새로운 알고리즘을 추가하려면 기존 코드를 수정하지 않고 새로운 전략 클래스를 추가하기만 하면 된다.

단점

  • 추가적인 클래스 및 인터페이스가 필요하기에 코드 복잡성이 증가될 수 있다.
  • 런타임 시에 알고리즘을 선택하는 데 추가적인 오버헤드 발생 가능하다.
  • 전략패턴을 구현하는 것이 어려울 수 있으므로, 적절한 분석과 설계가 필요하다.

 

strategy pattern 사용 예시 

Strategy 인터페이스 정의

interface Strategy {
    fun execute(a: Int, b: Int): Int
}

구체적인 전략 클래스 정의

class AddStrategy : Strategy {
    override fun execute(a: Int, b: Int): Int {
        return a + b
    }
}

class SubtractStrategy : Strategy {
    override fun execute(a: Int, b: Int): Int {
        return a - b
    }
}

class MultiplyStrategy : Strategy {
    override fun execute(a: Int, b: Int): Int {
        return a * b
    }
}

Context 클래스 정의

Context 클래스는 Strategy를 사용하는 클래스이다. 이 클래스는 Strategy 객체를 유지하고 이를 통해 작업을 수행한다.

class Context(private var strategy: Strategy) {
    fun setStrategy(strategy: Strategy) {
        this.strategy = strategy
    }

    fun executeStrategy(a: Int, b: Int): Int {
        return strategy.execute(a, b)
    }
}

사용 예시

fun main() {
    val context = Context(AddStrategy())
    println("10 + 5 = ${context.executeStrategy(10, 5)}")

    context.setStrategy(SubtractStrategy())
    println("10 - 5 = ${context.executeStrategy(10, 5)}")

    context.setStrategy(MultiplyStrategy())
    println("10 * 5 = ${context.executeStrategy(10, 5)}")
}