예시 코드

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

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

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

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

class Context(private var strategy: Strategy) {

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

    fun setStrategy(strategy: Strategy) {
        this.strategy = strategy
    }
}
  • Client
    fun main() {
        val context = Context(ConcreteStrategyAdd())
    
        println(context.executeStrategy(10, 5))
    
        context.setStrategy(ConcreteStrategySubtract())
        println(context.executeStrategy(10, 5))
    
        context.setStrategy(ConcreteStrategyMultiply())
        println(context.executeStrategy(10, 5))
    }

개념

Strategy Pattern이란 객체의 특정 행동(메소드)에 대해 다양한 알고리즘을 효율적으로 사용할 수 있게 하거나, 실행 중에 다른 알고리즘으로 전환할 수 있게 하는 디자인 패턴이다.

*효율적 → 코드 재사용성이 높고, 변화에 대응하기 좋은 구조

  1. 특정한 행동을 인터페이스로 만들고,
  1. 구체적인 행동 클래스를 구현한다.
  1. 행동을 할 주체(객체)에서 인터페이스를 참조하고, 구현체로는 인터페이스를 구현한 클래스를 받는다.
    • 행동을 하는 주체(객체)는 행동을 요청하지만 실제로 어떤 행동이 일어나는 지는 모른다.

비유

  • 네비게이션 어플

    상황

    • 기능 → 목적지 안내
    • 행동 → 목적지로 가는 경로 생성
    • 변화

      → 자차 경로, 도보 경로, 자전거 경로 등, 경로에 대한 옵션이 추가될 수 있음

      → 최단 시간, 최소 환승, 최소 비용 등, 경로 탐색 알고리즘이 달라질 수 있음

    적용

    1. 경로를 구하는 알고리즘을 인터페이스로 만든다.
      interface RouteStrategy {
      	fun buildRoute(from: LngLat, to: LngLat) : Route
      }
    1. 구체적인 경로 알고리즘 클래스를 구현한다.
      class MinimumTimeRoute : RouteStrategy {
      	override fun buildRoute(from: LngLat, to: LngLat) : Route {
      		// algorithm..
      	}
      }
      
      class MinimumCostRoute : RouteStrategy {
      	override fun buildRoute(from: LngLat, to: LngLat) : Route {
      		// algorithm..
      	}
      }
    1. 네비게이션은 루트를 구해달라는 요청만 하고, 실제로 어떤 알고리즘을 사용했는지는 모른다.
      class Navigator(private val routeStrategy: RouteStrategy) {
      
      	fun drawRoute(from: LngLat, to: LngLat) {
      		val route = buildRoute(from, to)
      		// draw to screen...
      	}
      
      	fun buildRoute(from: LngLat, to: LngLat) : Route {
      		routeStrategy.buildRoute(from, to)
      	}
      }
      fun main() {
      	val navi = Navigator(MinimumCostRoute())
      	navi.drawRoute(LngLat(37.232, 126.232), LngLat(37.56, 127.022))
      }

장단점

장점

  • OCP (개방-폐쇄 원칙)
    • 확장에는 열려있고, 수정에는 닫혀 있어야 한다.

단점

  • 행동에 대한 알고리즘 별로 없고, 잘 변하지 않는다면 보일러플레이트 코드가 많이 생긴다.
  • 클라이언트가 전략을 선택해야한다.


출처

https://refactoring.guru/ko/design-patterns/strategy

https://ko.wikipedia.org/wiki/전략_패턴


Uploaded by N2T

+ Recent posts