memento 구현에서 발생할 수있는 일반적인 문제는 종종 다른 종류의 객체의 내부 상태를 나타내는 많은 클래스가 필요하다는 것입니다. 또는 유물 구현은 객체 상태를 다른 형식 (예 : 직렬화 된 Java 객체)으로 직렬화해야합니다.
다음은 실행 취소/다시 실행 지원을 위해 상태를 캡처 할 클래스마다 특정 메모 클래스에 의존하지 않는 메모 구현에 대한 스케치입니다. 클래스 가비지 수집을 목적으로하기 때문에
public interface Reference<T> {
T get();
void set(T value);
}
이 java.lang.ref.Reference
의 추상화입니다 :
처음 소개되는 기본 개념이있다. 그러나 비즈니스 로직을 위해이를 사용해야합니다. 기본적으로 참조는 필드를 캡슐화합니다.그 사소한되지 않을 수도 있습니다 이러한 참조와 인스턴스 객체
public class Person {
private final Reference<String> lastName;
private final Reference<Date> dateOfBirth;
// constructor ...
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public Date getDateOfBirt() {
return dateOfBirth.get();
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth.set(dateOfBirth);
}
}
주, 그러나 우리는 여기에를 떠나 : 그래서 그들은 그와 같은 기능을 수행하기위한 것입니다. 기본적으로 Change
가 식별 가능한 객체의 상태에 대한 단일 식별 변화를 나타내는
public interface Caretaker {
void addChange(Change change);
void undo();
void redo();
void checkpoint();
}
public interface Change {
Change createReversal();
void revert();
}
:
지금 여기 메멘토 구현을위한 세부 사항입니다. Change
은 revert
메서드를 호출하여 되돌릴 수 있으며 createReversal
메서드로 만든 변경 내용을 되돌리면 되돌릴 수 있습니다. Caretaker
은 addChange
메서드를 통해 개체 상태에 대한 변경 사항을 누적합니다. undo
및 redo
메소드를 호출하여 Caretaker
은 다음 체크 포인트에 도달 할 때까지 모든 변경 사항을 되돌 리거나 다시 실행 (즉, 변경 취소 되돌리기)합니다. 검사 점은 모든 관찰 된 변경 사항이 모든 변경된 객체의 모든 상태를 유효한 하나의 유효한 구성으로 변환하는 변경으로 축적되는 지점을 나타냅니다. 체크 포인트는 대개 작업 전후에 생성됩니다. 이들은 checkpoint
메소드를 통해 생성됩니다.
이
public class ReferenceChange<T> implements Change {
private final Reference<T> reference;
private final T oldValue;
private final T currentReferenceValue;
public ReferenceChange(Reference<T> reference, T oldValue,
T currentReferenceValue) {
super();
this.reference = reference;
this.oldValue = oldValue;
this.currentReferenceValue = currentReferenceValue;
}
@Override
public void revert() {
reference.set(oldValue);
}
@Override
public Change createReversal() {
return new ReferenceChange<T>(reference, currentReferenceValue,
oldValue);
}
}
public class CaretakingReference<T> implements Reference<T> {
private final Reference<T> delegate;
private final Caretaker caretaker;
public CaretakingReference(Reference<T> delegate, Caretaker caretaker) {
super();
this.delegate = delegate;
this.caretaker = caretaker;
}
@Override
public T get() {
return delegate.get();
}
@Override
public void set(T value) {
T oldValue = delegate.get();
delegate.set(value);
caretaker.addChange(new ReferenceChange<T>(delegate, oldValue, value));
}
}
Reference
의 값이 어떻게 변경되었는지 나타내는 Change
이 존재 : 지금 여기
그리고는 Reference
으로 Caretaker
활용하는 방법이다. 이 Change
은 CaretakingReference
이 설정 될 때 만들어집니다. 이 구현에서는 구현 내에서 중첩 된 Reference
이 필요합니다. 의 revert
은 CaretakingReference
을 통해 새 addChange
을 트리거하지 않아야하기 때문입니다.
컬렉션 속성은 Reference
을 사용할 필요가 없습니다. 이 경우에는 보전을 실행하는 사용자 지정 구현을 사용해야합니다. Primitives는 autoboxing과 함께 사용할 수 있습니다.
이 구현은 필드 대신 직접 참조를 사용하여 추가 런타임 및 메모리 비용을 추론합니다.
호기심에서 벗어나 그것에 관한 위키 백과 항목을 읽으셨습니까? – fge
또한 다시 조사 할 때 다시 시작하는 동안 "유품 저장"을 유지 하시겠습니까? 귀하의 질문은 (나에게) 지속성에 관한 것으로 들리고, 지속성은 귀하의 필요와 환경에 따라 구현이 번창합니다. – fge
예 몇 번이나 스캔했지만 대부분 책 (GoF Book & Head First Design Patterns)을 사용했습니다. 및 다양한 다른 소스. –