Strategy Pattern in Swift

hyob·2020년 10월 7일
2

요약

어떤 객체의 행위를 런타임에 바꿀수 있도록 한다.
-> 객체의 행위를 Strategy로 만들어 두고, 객체의 행동(메소드) 수정이 필요할때, Strategy를 교체함으로서 객체의 행동을 바꾼다.

구현

import Foundation

protocol PlayStrategy {
    func play(game: Gamable)
}

class ClassicStrategy: PlayStrategy {
    func play(game: Gamable) {
        print("play classic")
    }
}

class ModernStrategy: PlayStrategy {
    func play(game: Gamable) {
        print("play modernly with \(game.playerCount) people")
    }
}

protocol Gamable {
    var playerCount: Int { get set }
    var playStrategy: PlayStrategy { get set }
    init(playerCount: Int, playStrategy: PlayStrategy)
}

extension Gamable {
    func play() {
        playStrategy.play(game: self)
    }
}

class Game: Gamable {
    var playerCount: Int

    var playStrategy: PlayStrategy

    required init(
        playerCount: Int,
        playStrategy: PlayStrategy = ClassicStrategy()
    ) {
        self.playerCount = playerCount
        self.playStrategy = playStrategy
    }
}


let game = Game(playerCount: 4)
game.play()
var modernGame = Game(playerCount: 6, playStrategy: ModernStrategy())
modernGame.play()
modernGame.playStrategy = ClassicStrategy()
modernGame.play()

제 사이드 프로젝트에 적용된 코드를 간략하게 다시 적었습니다. 허술해도 이해 부탁드려요..

결론

새로운 play 전략이 생길 경우 PlayStrategy프로토콜(인터페이스)를 채택하는 Stratgy클래스를 만들어 주면 됨.
기존의 play 코드를 수정할 필요가 없음. Gamable을 채택한 클래스 객체의 playStrategy 만 교체하면 됨.
--> 확장성을 보장해 줌. OCP 잘 지킴.

고민점

  1. Strategy 는 프로퍼티가 아니라, 각기 다른 전략의 알고리즘을 위한 함수를 위해 사용 되었기 때문에 스트럭트 말고 클래스로 선언했음.
    -> 값을 위한 것이 아니라 객체의 행위를 위한 것이라서 그랬는데, 아직 잘 모르겠다.

  2. Game은 클래스 스트럭트 모두 가능하나, 값을 복사할지 참조할지 잘 따져서 사용해야 할듯 함.

~~객체 지향이란 무엇일까.. 클래스 스트럭트는 아직도 고민이 됨..~~

profile
앵커리어에서 자소설닷컴을 개발하고 있습니다.

0개의 댓글