CS/디자인패턴
디자인패턴 - 전략 패턴
mintropy
2022. 6. 28. 15:55
전략 패턴을 사용하지 않고, Duck이라는 슈퍼클래스를 기반으로 각 구현체는 슈퍼클래스를 상속받아서 생성한다고 하자. 그러면 구현이 단순해 보일 수 있지만, 다른 문제를 마주치게 될 것이다. 예를 들어 오리가 나는 행동을 추가하고 싶다면, Duck클래스에 그러한 행동을 추가하는 방식으로 해결할 것이다.
여기서 큰 문제를 마주하게 된다.
특정 행동을 하거나 하지 않는 오리가 있다면, 또는 특정 행동을 다르게 하는 오리가 있다면 어떻게 해야되는가? |
이는 다음과 같은 경우를 의미한다.
- 어떤 오리가 수영하지 않는다고 하면, Duck클래스를 상속받은 후, 메서드 오버라이드 하여 특정 행동을 제한해야 하는가?
- 오리마다 우는 방식이나 소리가 다르다고 하면, 우는 행동은 모두 재작성해야 하는가?
이 방식은 상속받는 클래스가 많아질수록, 메서드가 많아질수록 문제를 일으킬 가능성이 높다
오리의 각 행동을 구현하는 인터페이스를 기반으로, 각 행동을 구현하는 방법을 적용할 수 있다.
그리고 Duck 클래스에서 각 행동을 바로 구현하는 것이 아니라, 위에서 정의한 인터페이스를 기반으로 실제 날거나 우는 행위를 할 수 있는 performQuack(), performFly() 메서드를 추가한다.
전략 패턴은 알고리즘 군(위의 예시에서 FlyBehavior, QuackBehavior)을 정의, 캡슐화하여 사용할 수 있도록 한다. 따라서 클라이언트로부터 알고리즘을 분리하여 독립적으로 변경할 수 있다. 이는 전략의 행위(메서드)를 더욱 다양하게 만들 수 있게 해 준다.
import abc
class Duck:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def display(self):
pass
def perform_fly(self):
self.fly_behavior.fly()
def perfrom_quack(self):
self.quack_behavior.quack()
class FlyBehavior:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def fly(self):
pass
class FlyWithWings(FlyBehavior):
def fly(self):
print("Fly with wings")
class FlyNoWay(FlyBehavior):
def fly(self):
print("Fly no way")
class QuackBehavior:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def quack(self):
pass
class Quack(QuackBehavior):
def quack(self):
print("Quack Quack")
class MuteQuack(QuackBehavior):
def quack(self):
print("Mute...")
class MallardDuck(Duck):
def __init__(self):
self.fly_behavior = FlyNoWay()
self.quack_behaviro = Quack()
def display(self):
print("Mallard Duck")
참조
- 헤드퍼스트 디자인패턴