GoF์ ๋์์ธ ํจํด, ๋ฉ๋ฉํ ํจํด์ ๋ํด ์์๋ณธ๋ค.
ํด๋น ๊ธ์, ๋ค์์ ์ฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ดํดํ๋ ๊ฒ์ด ํธ๋ฆฌํฉ๋๋ค.
ํต์ฌ ์์ฝ
- ๊ฐ์ฒด์ ์ํ๋ฅผ ๊ธฐ์ตํด๋์๋ค๊ฐ ํ์ํ ๋ ๊ธฐ์ตํด๋ ์ํ๋ก ๊ฐ์ฒด๋ฅผ ๋๋๋ฆฐ๋ค.
- ๊ฐ์ฒด์ ์ํ์ ๋ํ ๊ธฐ์ต์ ๋ค๋ฅธ ๊ฐ์ฒด์์๋ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ ๊ทผ
- ๊ฐ์ฒด์ ์ํ์ ๋ํ ๊ธฐ์ต ์์ฑ์ ์ค์ง ํด๋น ๊ฐ์ฒด๋ง์ด ํ ์ ์๋ค.
- ๊ฐ์ฒด์ ์ค๋ ์ท์ ์ ์ฅํด๋๋ ํจํด
์์
Code
Walker
//
// Walker.swift
// Memento
//
// Created by Choiwansik on 2023/02/07.
//
import Foundation
internal class Walker {
internal init(current: Coordinate, target: Coordinate) {
self.current = current
self.target = target
}
internal func walk(with action: String) {
self.actionList.append(action)
if action == "UP" {
self.current.addY(diff: +1)
} else if action == "RIGHT" {
self.current.addX(diff: +1)
} else if action == "DOWN" {
self.current.addY(diff: -1)
} else if action == "LEFT" {
self.current.addX(diff: -1)
}
}
internal func createMemento() -> Memento {
Memento(coordinate: self.current, actionList: self.actionList)
}
internal func restore(with memento: Memento) {
self.current = memento.coordinate
self.actionList = memento.actionList
}
internal var remainingDistance: Double {
let xSquare = pow(Double((self.current.x - self.target.x)), 2.0)
let ySquare = pow(Double((self.current.y - self.target.y)), 2.0)
return sqrt(Double(xSquare) + Double(ySquare))
}
internal var description: String {
self.actionList.map { "\($0)" }.joined(separator: " ")
}
private var current: Coordinate
private let target: Coordinate
private var actionList = Array<String>()
}
extension Walker {
internal class Memento {
internal init(coordinate: Coordinate, actionList: Array<String>) {
self.coordinate = coordinate
self.actionList = actionList
}
internal let coordinate: Coordinate
internal let actionList: Array<String>
}
}
internal struct Coordinate {
private(set) var x: Int
private(set) var y: Int
internal mutating func addX(diff: Int) {
self.x += diff
}
internal mutating func addY(diff: Int) {
self.y += diff
}
}
main
//
// main.swift
// Memento
//
// Created by Choiwansik on 2023/02/07.
//
import Foundation
internal func main() {
let start = Coordinate(x: 0, y: 0)
let destination = Coordinate(x: 10, y: 10)
let walker = Walker(current: start, target: destination)
let actions = ["UP", "RIGHT", "DOWN", "LEFT"]
var minDistance = Double.greatestFiniteMagnitude
var memento: Walker.Memento?
while true {
let action = actions[Int.random(in: 0..<actions.count)]
walker.walk(with: action)
let remainDistance = walker.remainingDistance
print(remainDistance)
if remainDistance == .zero {
break
}
// ๊ฑฐ๋ฆฌ๊ฐ ์์์ง๋ฉด ์ ์ฅํจ
if minDistance > remainDistance {
minDistance = remainDistance
memento = walker.createMemento()
// ๊ฑฐ๋ฆฌ๊ฐ ์ปค์ง๋ ๊ฒฝ์ฐ ์ด์ ์ํ๋ฅผ ๋ถ๋ฌ์ด
} else if let memento {
walker.restore(with: memento)
}
}
print("walker's path: \(walker.description)")
}
main()
ํ์ฉ์ฑ
- ์ด๋ค ๊ฐ์ฒด์ ์ํ์ ๋ํ ์ค๋ ์ท์ ์ ์ฅํ ํ ๋์ค์ ์ด ์ํ๋ก ๋ณต๊ตฌํด์ผ ํ ๋
- ์ํ๋ฅผ ์ป๋๋ฐ ํ์ํ ์ง์ ์ ์ธ ์ธํฐํ์ด์ค๋ฅผ ๋๋ฉด ๊ทธ ๊ฐ์ฒด์๊ตฌํ ์ธ๋ถ์ฌํญ์ด ๋๋ฌ๋๋ ๊ฒฝ์ฐ
- ์บก์ํ๊ฐ ๊นจ์ง
๊ฒฐ๊ณผ
- ์บก์ํ๋ ๊ฒฝ๊ณ๋ฅผ ์ ์งํ ์ ์๋ค.
- ๊ฒฐ๊ตญ ๋ฉ๋ฉํ ๊ฐ์ฒด๋ ํด๋น ๊ฐ์ฒด ๋ด๋ถ์์ ์ฒ๋ฆฌํ๊ฒ ๋๋ฏ๋ก ๋ด๋ถ ๊ตฌํ ์ฌํญ์ ์จ๊ฒจ์ง๋ค.
- ์ฌ์ฉ๋ ๋ฃ์ด์ค์ผ๋ก์จ ์ฒ๋ฆฌ๋๋ ์บก์ํ ๋ณดํธ๋๋ค.
- ์ํ ์ ์ฅ์ ๋ํ ์ฑ
์์ ๋ถ๋ฆฌํ ์ ์๋ค.
- Walker๋ ๋ฐ์์ ๋ฃ์ด์ค ๋ฟ์ด๋ค.
- ๋ง์ ์์ ์ ๋ณด ์ ์ฅ, ๋น๋ฒํ๊ฒ ์ํ ๋์ฒดํ ๊ฒฝ์ฐ ๋น์ฉ์ด ๋์์ง ์ ์๋ค.
- ๊ณ์ํด์ ์ ์ฅํ๊ณ ๋ฎ์ด์จ์ผ ํ๊ธฐ ๋๋ฌธ์ ์ฐ์ฐ๋์ ์ฆ๋๋ ์ ์๋ค.
- ๋ฉ๋ฉํ ๊ฐ์ฒด๋ฅผ ๋ฐ๊ณ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด (
main
)๋ ์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ ๊ด๋ฆฌํ๋๋ฐ ํ์ํ ๋น์ฉ์ ์ ์ ์๋ค.- ๋จ์ํ ๋ง๋ค์ด์ ์ฌ์ฉ๋ง ํ๋ค๋ฉด, ๊ฐ์ฒด ๋ด๋ถ ๋ชจ๋ ์ํ๊ฐ ๋ณต์ฌ ๋ฑ์ ๋น์ฉ์ ์์ง๋ชปํ๊ณ ์ฒ๋ฆฌํ๊ฒ ๋๋ค.
์๊ฐํด๋ณผ ์
- Swift์์ ๊ฐ์ฒด ์์นด์ด๋น ํ๋ ๊ฒ์ด ์ด์ ๋น์ท (
NSCoding
) - NSObject์ ๋ํด ์์นด์ด๋นํ ๋๋ ํด๋น ๊ฐ์ฒด ์์์ ์ ์ํด์ฃผ์์ด์ผ ํจ
- ์๋ฒฝํ ๋งค์นญ๋์ง ์์ ์๋ ์์ง๋ง ๋น์ทํ๋ค๊ณ ์๊ฐ