Strategy Pattern 이란?
Strategy Pattern (전략 패턴)은 교환 가능한 객체들을 정의해두고 Strategy protocol을 이용하여 런타임에 설정하거나 변환하는 패턴
Object using a Strategy : Strategy protocol을 이용하는 객체
Strategy protocol : 모든 strategy가 반드시 구현해야 할 메서드들을 정의하고 있는 프로토콜
Strategies : Strategy 프로토콜을 준수하는 교환가능한 객체들
Strategy Pattern 예시코드
// MARK: - Strategy Protocol
protocol MovieRatingStrategy {
var ratingServiceName: String { get }
func fetch(fot title: String, success: @escaping ((_ rating: String, _ review: String) -> Void))
}
// MARK: - Concrete Strategy 1
class RottenTomatoesClient: MovieRatingStrategy {
let ratingServiceName: String = "Rotten Tomatoes"
func fetch(fot title: String, success: @escaping ((String, String) -> Void)) {
// 통신을 통해 값을 받아온다고 생각합니다.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
let rating = "95%"
let review = "It rocked!"
success(rating, review)
}
}
}
// MARK: - Concrete Strategy 2
class IMDbClient: MovieRatingStrategy {
let ratingServiceName: String = "IMDb"
func fetch(fot title: String, success: @escaping ((String, String) -> Void)) {
// 통신을 통해 값을 받아온다고 생각합니다.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
let rating = "3 / 10"
let review = "It was terrible!"
success(rating, review)
}
}
}
// MARK: - Object using a Strategy
class ViewController: UIViewController {
var movieRatingClient: MovieRatingStrategy!
let ratingServiceNameLabel = UILabel()
let ratingLabel = UILabel()
let reviewLabel = UILabel()
init(movieRatingClient: MovieRatingStrategy) {
self.movieRatingClient = movieRatingClient
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
ratingServiceNameLabel.text = movieRatingClient.ratingServiceName
movieRatingClient.fetch(fot: "movie title") { rating, review in
self.ratingLabel.text = rating
self.reviewLabel.text = review
}
}
}
Strategy Pattern 사용하는 이유
- 정책에 따라 유연하게 동작하는 메서드를 캡슐화함으로써 정책마다 로직이 if-else 문으로 분기 하는것을 방지
- 새로운 정책이 추가되거나 기존의 정책이 사라지더라도, 사용하는 쪽에서는 코드를 수정할 필요가 없다.
- 기능을 사용하는 부분과 구현하는 부분을 명확히 분리한다
SOLID 관점에서 바라본 Strategy Pattern
- 기능 확장에는 열려있고 변경에는 닫혀있는 개방 폐쇄 원칙(OCP)도 따르는 구조를 갖게 된다.
- 인터페이스로 타입을 추상화하지 않았다면, 구현체를 직접 의존하게 되고 이는 두 객체간의 강한 결합으로 런타임에 메서드를 변경하지 못하게 된다. 사용객체과 구현객체 모두 추상화에 의존하게 하므로서 느슨한 결합을 가져가고 있으므로 의존성 역전 원칙(DIP)도 잘 따르고 있다고 할 수 있다.
참고자료
https://velog.io/@ljinsk3/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-Strategy-Pattern
'Object-Oriented Programming > Design Pattern' 카테고리의 다른 글
Factory Method Pattern, 팩토리 메소드 패턴 (0) | 2022.05.09 |
---|---|
Facade Pattern (0) | 2022.05.04 |
GoF Design Patterns (0) | 2022.03.14 |
Repository 패턴 (0) | 2021.12.08 |
Singleton Pattern (0) | 2021.02.17 |