GoF의 디자인 패턴, 전략 패턴에 대해 알아본다.
해당 글은, 다음의 코드를 기반으로 이해하는 것이 편리합니다.
//
// main.swift
// Visitor
//
// Created by Choiwansik on 2023/02/21.
//
import Foundation
internal func main() {
let list1 = ItemList()
list1.add(unit: Item(value: 10))
list1.add(unit: Item(value: 20))
list1.add(unit: Item(value: 30))
let list2 = ItemList()
list2.add(unit: Item(value: 40))
list2.add(unit: Item(value: 50))
list2.add(unit: list1)
let list3 = ItemList()
list3.add(unit: Item(value: 60))
list3.add(unit: list1)
list3.add(unit: list2)
let sum = SumVisitor()
let avg = AvgVisitor()
list1.accept(visitor: sum)
list1.accept(visitor: avg)
print("List1 SUM: \(sum.value)")
print("List1 AVG: \(avg.value)")
list2.accept(visitor: sum)
list2.accept(visitor: avg)
print("List2 SUM: \(sum.value)")
print("List2 AVG: \(avg.value)")
list3.accept(visitor: sum)
list3.accept(visitor: avg)
print("List3 SUM: \(sum.value)")
print("List3 AVG: \(avg.value)")
}
main()
List1 SUM: 60
List1 AVG: 20.0
List2 SUM: 210
List2 AVG: 26.25
List3 SUM: 480
List3 AVG: 28.235294117647058
//
// Unit.swift
// Visitor
//
// Created by Choiwansik on 2023/02/21.
//
import Foundation
internal protocol Unit {
func accept(visitor: Visitor)
}
//
// Item.swift
// Visitor
//
// Created by Choiwansik on 2023/02/21.
//
import Foundation
internal struct Item: Unit {
internal let value: Int
internal func accept(visitor: Visitor) {
visitor.visit(unit: self)
}
}
//
// ItemList.swift
// Visitor
//
// Created by Choiwansik on 2023/02/21.
//
import Foundation
internal class ItemList: Unit {
internal func add(unit: Unit) {
self.list.append(unit)
}
internal func accept(visitor: Visitor) {
self.list.forEach { visitor.visit(unit: $0) }
}
private(set) var list = Array<Unit>()
}
//
// Visitor.swift
// Visitor
//
// Created by Choiwansik on 2023/02/21.
//
import Foundation
internal protocol Visitor {
func visit(unit: Unit)
}
//
// SumVisitor.swift
// Visitor
//
// Created by Choiwansik on 2023/02/21.
//
import Foundation
internal class SumVisitor: Visitor {
internal var value: Int {
self.sum
}
internal func visit(unit: Unit) {
if let item = unit as? Item {
sum += item.value
} else {
unit.accept(visitor: self)
}
}
private(set) var sum: Int = .zero
}
//
// AvgVisitor.swift
// Visitor
//
// Created by Choiwansik on 2023/02/21.
//
import Foundation
internal class AvgVisitor: Visitor {
internal var value: Double {
Double(self.sum) / Double(self.count)
}
internal func visit(unit: Unit) {
if let item = unit as? Item {
self.sum += item.value
self.count += 1
} else {
unit.accept(visitor: self)
}
}
private(set) var sum = 0
private(set) var count = 0
}