본문 바로가기
CS/디자인패턴

[Head First 디자인패턴] 1. Strategy Pattern (전략 패턴)

by Mintta 2022. 10. 14.
import UIKit

//MARK: Fly Protocol
protocol FlyBehavior {
    func fly()
}

class FlyWithWings: FlyBehavior {
    func fly() {
        print("날고 있어요~!")
    }
}

class FlyNoWay: FlyBehavior {
    func fly() {
        print("저는 날 수 없습니다...")
    }
}

class FlyWithRocket: FlyBehavior {
    func fly() {
        print("🚀로켓으로 날아갑니다!")
    }
}

//MARK: Quack Protocol
protocol QuackBehavior {
    func quack()
}

class Quack: QuackBehavior {
    func quack() {
        print("꽥 !")
    }
}

class MuteQuack: QuackBehavior {
    func quack() {
        print("조용....")
    }
}

class Squeak: QuackBehavior {
    // 장난감 오리
    func quack() {
        print("삑")
    }
}

//MARK: Duck
// abstract method
protocol DuckProtocol {
    func display()
}

class Duck {
    var flyBehavior: FlyBehavior!
    var quackBehavior: QuackBehavior!
    
    init(flyBehav: FlyBehavior, quackBehav: QuackBehavior) {
        self.flyBehavior = flyBehav
        self.quackBehavior = quackBehav
    }
    
    func performFly() {
        flyBehavior.fly()
    }
    
    func performQuack() {
        quackBehavior.quack()
    }
    
    func swim() {
        print("모든 오리는 물에 뜰 수 있습니다")
    }
    
    func setFlyBehavior(flyBehavior: FlyBehavior) {
        self.flyBehavior = flyBehavior
    }
    
    func setQuackBehavior(quackBehavior: QuackBehavior) {
        self.quackBehavior = quackBehavior
    }
}

//MARK: 오리들
class MallardDuck: Duck, DuckProtocol {
    override init(flyBehav: FlyBehavior, quackBehav: QuackBehavior) {
        super.init(flyBehav: flyBehav, quackBehav: quackBehav)
    }
    
    func display() {
        print("저는 물오리입니다!")
    }
}

class ModelDuck: Duck, DuckProtocol {
    override init(flyBehav: FlyBehavior, quackBehav: QuackBehavior) {
        super.init(flyBehav: flyBehav, quackBehav: quackBehav)
    }
    
    func display() {
        print("장난감 오리입니다")
    }
}



let duck = MallardDuck(flyBehav: FlyWithWings(), quackBehav: Quack())
duck.performQuack()
duck.performFly()

let model = ModelDuck(flyBehav: FlyNoWay(), quackBehav: Quack())
model.performFly()
model.setFlyBehavior(flyBehavior: FlyWithRocket())
model.performFly()

헤드퍼스트 디자인패턴의 1장인 Strategy Pattern의 대한 예제를 Swift로 구현해보았다.

 

한가지 조금 찝찝한 점은 java의 abstract method와 abstract class를 DuckProtocol로 구현해서 아래 Duck을 상속받는 MallardDuck, ModelDuck등이 Duck과 DuckProtocol 두가지를 채택하고 있다는 점이다.

(이 부분에 대한 피드백을 듣고 싶은데 누구한테 물어야할지 모르겠네….)

 

Strategy Pattern(전략 패턴)은 알고리즘군을 정의하고 캡슐화해서 각각의 알고리즘군을 수정해서 쓸 수 있게 해준다. 여기서 알고리즘군은 오리들의 행동을 말할 수 있겠다. 전략 패턴을 사용하면 클라이언트로부터 알고리즘을 분리해서 독립적으로 변경할 수 있겠다. 또한 객체에 독립적으로 구성되기 때문에 Decoupling, 결합도를 낮출 수 있다.

 

 

 

객체지향 원칙

  • 바뀌는 부분은 캡슐화한다
  • 상속보다는 구성을 활용한다
    = 오리들에게 Fly, Quack이 있었는데 이를 Duck클래스의 메소드로 들고 있는게 아닌 오리가 FlyBehavior, QuackBehavior로 구성되게끔 만든다 !
  • 구현보다는 인터페이스에 맞춰서 프로그래밍한다! → Swift에서는 Protocol

댓글