행동에 관련된 패턴
Runtime 중에 알고리즘을 선택하게 한다.
약한 결합 중 객체를 바꿀 수 있고, 이는 분기마다 다른 선택을 가능케 한다. 알고리즘을 바꾸더라도 돌아갈 수 있도록 하여 고정을 하지 않는다.
하나의 알고리즘을 직접 Implementing 하는 대신 어떠한 알고리즘을 사용할 지 Runtime Instruction을 받는다.

해당 패턴은 런타임 중에 알고리즘을 선택하여 객체 동작을 실시간으로 적용할 수 있다.
전략이란 기능, 동작, 알고리즘 등 특정한 목표를 수행하기 위한 행동을 의미한다.

1.1 메모리가 적은 환경 -> 느리지만 적은 비용의 메모리 Strategy
1.2 메모리가 많은 환경 -> 빠르지만 많은 비용의 메모리 Strategy
1.3 복잡한 계산이 필요한 태스크가 있다고 가정할 떄
1.4 버그가 있을지도 모르는 고숙 알고리즘
1.5 저속이지만 확실한 계산을 실행하는 알고리즘
보통 프로그래밍을 할 때 메소드 내부에 동화된 형태로 알고리즘을 구현한다. 그러나 Strategy 패턴에서는 알고리즘의 부분을 다른 부분과 의식적으로 분리해서 알고리즘의 API만을 규정한다. 그리고 프로그램에서 위임에 의해 알고리즘을 이용한다.
이것은 프로그램을 복잡하게 만드는 것처럼 보이지만 실제로는 그렇지 않다. 개량 및 수정에 용이하기 때문이다. 더욱이 위임이라는 느슨한 연결을 사용하고 있으므로 용이한 교환에 최적화되어 있다.
Strategy 패턴을 활용해서 플레이어의 무기에 관련된 코드를 짜보자.
from abc import *
class Weapon(metaclass=ABCMeta):
@abstractmethod
def offensive(self):
pass
class Sword(Weapon):
def offensive(self):
print("칼을 휘두르다")
class Shield(Weapon):
def offensive(self):
print("방패로 밀치다")
class CrossBow(Weapon):
def offensive(self):
print("활을 쏘다")
class TakeWeaponStrategy:
def __init__(self):
self.weapon = 0
def setWeapon(self, weapon: Weapon):
self.weapon = weapon
def attack(self):
self.weapon.offensive()
# 플레이어 손에 무기 착용 전략을 설정
hand = TakeWeaponStrategy()
# 플레이어가 검을 들도록 전략 설정
hand.setWeapon(Sword())
hand.attack() # "칼을 휘두르다"
# 플레이어가 방패를 들도록 전략 변경
hand.setWeapon(Shield())
hand.attack() # "방패로 밀치다"
# 플레이어가 석궁을 들도록 전략 변경
hand.setWeapon(CrossBow())
hand.attack() # "활을 쏘다"
# Dependency Inversion Principle(DIP) 따름
# 다형성을 통한 실시간 공격전략의 교체 가능
# TakeWeaponStrategy 함수 수정이 필요 없음