Caretaker객체는 Originator객체에 메멘토 객체를 요청한다.
또한, 요청한 시간을 저장하며, 받는 메멘토 객체를 다시 원조본 객체에게 돌려주는데, 이를 상호작용 다이어그램으로 나타내면 다음과 같다.
메멘토 객체는 수동적이다. 메멘토 객체를 생성한 원조본 객체만이 상태를 설정하고 읽어올 수 있다.
// Memento 프로토콜
protocol MementoProtocol {
var state: [String] { get }
}
// Originator 프로토콜
protocol OriginatorProtocol {
func createMemento() -> MementoProtocol
func restore(memento: MementoProtocol)
}
// Caretaker 프로토콜
protocol CaretakerProtocol {
func saveState(originator: OriginatorProtocol)
func restoreState(originator: OriginatorProtocol, index: Int)
func showHistory()
}
// Drawing 클래스
class Drawing: OriginatorProtocol {
private var shapes: [String] = []
func addShape(_ shape: String) {
shapes.append(shape)
}
func showShapes() {
print("현재 도형들: \(shapes.joined(separator: ", "))")
}
func createMemento() -> MementoProtocol {
return DrawingMemento(state: shapes)
}
func restore(memento: MementoProtocol) {
guard let memento = memento as? DrawingMemento else { return }
self.shapes = memento.state
}
}
// DrawingMemento 클래스
class DrawingMemento: MementoProtocol {
let state: [String]
init(state: [String]) {
self.state = state
}
}
// DrawingCaretaker 클래스
class DrawingCaretaker: CaretakerProtocol {
private var mementos: [MementoProtocol] = []
func saveState(originator: OriginatorProtocol) {
mementos.append(originator.createMemento())
}
func restoreState(originator: OriginatorProtocol, index: Int) {
guard index < mementos.count else {
print("해당 인덱스 \(index)에 저장된 상태가 없습니다.")
return
}
originator.restore(memento: mementos[index])
}
func showHistory() {
for (index, memento) in mementos.enumerated() {
guard let memento = memento as? DrawingMemento else { continue }
print("상태 \(index): \(memento.state.joined(separator: ", "))")
}
}
}
// 사용 예제
let drawing = Drawing()
let caretaker = DrawingCaretaker()
// 도형 추가 및 상태 저장
drawing.addShape("원")
caretaker.saveState(originator: drawing)
drawing.addShape("사각형")
caretaker.saveState(originator: drawing)
drawing.addShape("삼각형")
caretaker.saveState(originator: drawing)
// 현재 도형 상태 출력
drawing.showShapes()
// 상태 복원
caretaker.restoreState(originator: drawing, index: 1)
drawing.showShapes()
// 상태 복원 이력 출력
caretaker.showHistory()
// 현재 도형들: 원, 사각형, 삼각형
// 현재 도형들: 원, 사각형
// 상태 0: 원
// 상태 1: 원, 사각형
// 상태 2: 원, 사각형, 삼각형