swift 디자인패턴 - Strategy Pattern
언제 사용하나?
어떤 상황에서 사용할 알고리즘이 여러개 존재할때 사용한다.
알고리즘을 런타임에서 변경해야 할때 사용한다.
예) 결제를 할때 결제 수단 선택하기 - 신용카드로 결제, 마일리지로 결제, 포인트로 결제, 쿠폰으로 결제 등등
검색할때 검색 조건 선택하기 - 전체검색, 이미지검색, 뉴스 검색 등등
장점
런타임에서 알고리즘을 변경 할 수 있다.
알고리즘을 사용하는 코드와 알고리즘을 구현하는 코드를 분리할 수 있다.
알고리즘을 사용하는 코드 context를 변경하지 않고도 새로운 전략 기능을 추가 할 수 있다.
단점
알고리즘이 몇개 없을때 복잡성을 증가 시킬수 있다.
strategy, context간 통신오버헤드가 발생한다.
목표
인터페이스 개념을 이해한다. 델리게이트 개념을 이해한다. 전력 패턴 개념을 이해한다.
인터페이스?
키보드나 디스플레이 처럼 사람과 컴퓨터를 연결하는 장치이다.
두 객체를 연결시키는 접점.
기능에 대한 선언과 구현이 분리가 되어 있다.
기능을 통로로 사용할 수 있다.
델리게이트?
델리게이트 : 위임하다, 떠넘기다. 두객체간의 관계에서 나타난다.
특정객체의 기능을 사용하기 위해 다른 객체의 기능을 호출하는 것.
예제 1
전략패턴
여러 알고리즘을 하나의 추상적인 접근점을 만들어 접근점에서 서로 교환 가능하도록 하는 패턴
요구사항
게임에서 캐릭터와 무기를 구현해보시오
무기는 두가지 종류가 있다.
-칼, -검
캐릭터는 무기를 칼을 선택할 수도 있고, 검을 선택할 수도 있다.
import Foundation
/// 전략 인터페이스
protocol Weapon {
func attack()
}
/// 칼 공격 전략
class Knife : Weapon {
func attack() {
print("칼 공격")
}
}
/// 손공격 전략
class Hand : Weapon {
func attack() {
print("손 공격")
}
}
/// 전략 패턴 클래스를 사용할 주체 클래스
class GameCharacter {
/// 접근점 - 사용할 무기
private var weapon : Weapon?
/// 무기 교환 가능
func setWeapon(weapon : Weapon){
self.weapon = weapon
}
/// 공격
func attack() {
if weapon == nil {
print("36계 줄행랑")
}else{
/// 델리게이트
/// GameCharacter 는 무기 사용하는 기능을 Weapon 에 위임했다.
weapon?.attack()
}
}
}
let character = GameCharacter()
character.attack() //36계 줄행랑
character.setWeapon(weapon: Hand())
character.attack() //손 공격
예제 2
Context : Strategy 객체를 소유하고 동적으로 행위를 실행하는 객체
Strategy : ConcreteStrategy 객체의 부모 객체로서 동적으로 지정할 행위에 대한 알고리즘 인터페이스를 정의 하는 추상객체
ConcreteStrategy : Strategy 인터페이스를 구현한 객체
import Foundation
/// 전략 패턴
protocol Strategy{
func doAlgorithm <T: Comparable> (data:[T]) -> [T]
}
/// 전략 A - 순서대로 정렬시키기 알고리즘
class ConcreteStrategyA : Strategy {
func doAlgorithm<T>(data: [T]) -> [T] where T : Comparable {
return data.sorted()
}
}
/// 전략 B - 반대로 정렬시키기 알고리즘
class ConcreteStrategyB : Strategy {
func doAlgorithm<T>(data: [T]) -> [T] where T : Comparable {
return data.sorted(by: >)
}
}
class Context {
//접근점 - 프로토콜
private var strategy: Strategy
init(strategy: Strategy) {
self.strategy = strategy
}
/// 교환 가능
func update(strategy:Strategy){
self.strategy = strategy
}
func doBusinessLogic(){
/// 델리게이트
/// Context 는 정렬 기능을 Strategy 에 위임했다.
let result = strategy.doAlgorithm(data: ["a", "b","c","d","e","f"])
print(result.joined(separator: ","))
}
}
/// 사용
/// 순서대로 정렬
let context = Context(strategy: ConcreteStrategyA())
context.doBusinessLogic()
/// 반대로 정렬
context.update(strategy: ConcreteStrategyB())
context.doBusinessLogic()
참고
'아이폰 개발 > 디자인 패턴' 카테고리의 다른 글
swift 디자인 패턴 - 전략패턴(스트래티지 패턴) (0) | 2022.11.02 |
---|---|
디자인 패턴 - solid 원칙 정리 1 (0) | 2022.11.02 |
swift 디자인패턴 - State Pattern (0) | 2021.08.22 |
swift 디자인패턴 - Facade Pattern (0) | 2021.08.21 |
swift 디자인패턴 - Adapter Pattern (0) | 2021.08.21 |