전략 패턴(Strategy Pattern)은 알고리즘군을 정의하고 캡슐화해서 각각의 알고리즘군을 수정해서 쓸 수 있게 해줍니다. 전략패턴을 사용하면 클라이언트로부터 알고리즘을 분라해서 독립적으로 변경 할 수 있습니다.
Duck이라는 추상 클래스를 만든다.
" 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분과 분리한다."
Duck은 날 수 있는 기능 performfly,
울음소리 performQuack이 있다.
'물오리'는 날 수 있지만, '고무오리'는 날 수 없다.
"구현보다는 인터페이스에 맞춰서 프로그래밍한다."
그렇기에 각 행동을 나는 행동 FlyBehavior,우는 행동QuackBehavior 인터페이스로 만든다.
"상속보다는 구성을 활용한다."
fly(),quack()의 메소드를 성격별로 각 클래스에서 구성한다.
MallardDuck은 구성된 인터페이스에서 활용될 수 있다.
"이런 식으로 디자인하면 다른 형식의 객체에서도 나는 행동과 꽥꽥거리는 행동을 재사용 할 수있다. 그리고 기존의 행동클래스를 수정하거나 날아다니는 행동을 사용하는 Duck클래스를 전혀 건들지 않고도 새로운 행동을 추가 할 수 있다."
FlyBehavior과 QuackBehavior 인터페이스(프로토콜)를 불러온뒤
각 메소드에서 재사용.
생성자 초기값으로 프로토콜에대한 매개변수를 가져옴.
perform~은 behavior에 대한 메소드.
setFlyBehavior과 setQuackBehavior은, 서브클래스(Mallard) 생성자에서 인스턴스를 만드것이 아닌 서브클래스(Mallard)에서 세터메소드(setterMethod) 호출하려고 만들어 줌.
//Duck이라는 슈퍼클래스 생성
public class Duck {
private var flyBehavior : FlyBehavior
private var quackBehavior : QuackBehavior
init(flyBehavior: FlyBehavior, quackBehavior: QuackBehavior) {
self.flyBehavior = flyBehavior
self.quackBehavior = quackBehavior
}
public func performFly() {
flyBehavior.fly()
}
public func performQuack(){
quackBehavior.quak()
}
func setFlyBehavior(flyBehavior: FlyBehavior) {
self.flyBehavior = flyBehavior
}
func setQuackBehavior(quackBehavior: QuackBehavior) {
self.quackBehavior = quackBehavior
}
func display(){
print("오리")
}
}
protocol FlyBehavior{
func fly()
}
public class FlyWithWings : FlyBehavior{
func fly(){
print("날아올라! 저하늘 ~~ ")
}
}
public class FlyNoWay : FlyBehavior{
func fly() {
print("못날아여")
}
}
protocol QuackBehavior {
func quak()
}
public class Quack : QuackBehavior{
func quak() {
print("꽥꽥")
}
}
MallardDuck은 Duck의 서브 클래스이기때문에
생성자 초기값을 super.init()으로 해줬다.
public class MallardDuck : Duck{
// MallardDuck클래스의 생성자 기본값은 FlyNoWay(),MuteQuack()이다.
init(){
super.init(flyBehavior: FlyNoWay(),quackBehavior: MuteQuack())
}
override func display() {
print("물오리")
}
}
실행중에 오리의 행동을 바꾸고 싶으면 원하는 행동에 해당하는 Duck의 세터 메소드를 호출하면된다.
let mallardDuck : Duck = MallardDuck()
mallardDuck.display()
print("------------mallardDuck기본값------------")
mallardDuck.performFly()
mallardDuck.performQuack()
print("------------세터메소드를 사용하여 동적으로 바꿔줌------------")
mallardDuck.setFlyBehavior(flyBehavior: FlyWithWings())
mallardDuck.performFly()
mallardDuck.setQuackBehavior(quackBehavior: Quack())
mallardDuck.performQuack()