GoF์ ๋์์ธ ํจํด, ์ ๋ต ํจํด์ ๋ํด ์์๋ณธ๋ค.
ํด๋น ๊ธ์, ๋ค์์ ์ฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ดํดํ๋ ๊ฒ์ด ํธ๋ฆฌํฉ๋๋ค.
ํต์ฌ ์์ฝ
- ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ๋ถ๋ฆฌํด์ฃผ๋ ํจํด
- ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฐฉ์์ ๊ธฐ์กด์ ์์ค ์ฝ๋ ๋ณ๊ฒฝ ์์ด ์๋ก์ด ํด๋์ค ์ถ๊ฐ๋ง์ผ๋ก ํ์ฅ ๊ฐ๋ฅํจ
- ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ Composite Pattern์ ์ฌ์ฉํจ
์์
Code
main
//
// 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
//
// Unit.swift
// Visitor
//
// Created by Choiwansik on 2023/02/21.
//
import Foundation
internal protocol Unit {
func accept(visitor: Visitor)
}
Item
//
// 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
//
// 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
//
// Visitor.swift
// Visitor
//
// Created by Choiwansik on 2023/02/21.
//
import Foundation
internal protocol Visitor {
func visit(unit: Unit)
}
SumVisitor
//
// 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
//
// 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
}
ํ์ฉ์ฑ
- ๊ฐ์ฒด ๊ตฌ์กฐ์ ์ฒ๋ฆฌ๋ก์ง์ ๋ถ๋ฆฌํ์ฌ ์ ์ง๋ณด์์ ํ์ฅ์ฑ์ ํฅ์์ํฌ ์ ์๋ค.
- ๊ฐ์ฒด ๊ตฌ์กฐ๋ ๋์ผํ๋, ์ฐ์ฐ์ ์ถ๊ฐํ๊ณ ์ถ์ ๋
์๊ฐํด๋ณผ ์
- ์ฝ๋์ ๋ณต์ก์ฑ์ด ์ฆ๊ฐ๋ ์ ์๋ค.
- ๊ตฌ์กฐ๋ฅผ ๋ฐ๊พธ์ง ์๊ณ ์๋ก์ด ๋์์ ์ถ๊ฐํ ์ ์์ผ๋, ๊ฐ์ฒด ์์๊ฐ Visitor ์ธํฐํ์ด์ค์ ์์กดํ๊ฒ ๋๋ค.