제 생각에는 UNDO / REDO는 두 가지 방식으로 광범위하게 구현 될 수 있습니다. 1. 명령 수준 (명령 수준 실행 취소 / 다시 실행이라고 함) 2. 문서 수준 (전역 실행 취소 / 다시 실행이라고 함)
명령 수준 : 많은 답변이 지적했듯이 이것은 Memento 패턴을 사용하여 효율적으로 달성됩니다. 명령이 작업 저널 화도 지원하는 경우 다시 실행이 쉽게 지원됩니다.
제한 사항 : 명령 범위를 벗어나면 실행 취소 / 다시 실행이 불가능하므로 문서 수준 (글로벌) 실행 취소 / 다시 실행으로 이어집니다.
많은 메모리 공간을 포함하는 모델에 적합하기 때문에 귀하의 사례는 전역 실행 취소 / 다시 실행에 적합하다고 생각합니다. 또한 선택적으로 실행 취소 / 다시 실행하는 데 적합합니다. 두 가지 기본 유형이 있습니다.
- 모든 메모리 실행 취소 / 다시 실행
- 개체 수준 실행 취소 다시 실행
"모든 메모리 실행 취소 / 다시 실행"에서 전체 메모리는 연결된 데이터 (예 : 트리, 목록 또는 그래프)로 처리되고 메모리는 OS가 아닌 응용 프로그램에서 관리됩니다. 따라서 C ++의 경우 new 및 delete 연산자가 오버로드되어보다 구체적인 구조를 포함하여 a. 노드가 수정 된 경우 b. 데이터 보유 및 지우기 등, 기본적으로 전체 메모리를 복사하여 (메모리 할당이 이미 고급 알고리즘을 사용하여 응용 프로그램에 의해 최적화되고 관리된다고 가정) 스택에 저장하는 것입니다. 메모리의 복사본이 요청되면 얕은 또는 깊은 복사본이 있어야하는 필요성에 따라 트리 구조가 복사됩니다. 수정 된 변수에 대해서만 전체 복사가 작성됩니다. 모든 변수는 사용자 지정 할당을 사용하여 할당되므로 응용 프로그램은 필요한 경우 삭제할시기를 최종 결정합니다. 실행 취소 / 다시 실행을 분할해야하는 경우 작업 세트를 프로그래밍 방식으로 선택적으로 실행 취소 / 다시 실행해야하는 경우 상황이 매우 흥미로워집니다. 이 경우, 해당 새 변수, 삭제 된 변수 또는 수정 된 변수에만 플래그가 주어 지므로 실행 취소 / 다시 실행은 해당 메모리 만 실행 취소 / 다시 실행합니다. 개체 내에서 부분 실행 취소 / 다시 실행을 수행해야하는 경우 상황이 더욱 흥미로워집니다. 이러한 경우 "방문자 패턴"이라는 새로운 아이디어가 사용됩니다. "개체 수준 실행 취소 / 다시 실행"이라고합니다. 또는 삭제 된 변수 또는 수정 된 변수에는 플래그가 주어 지므로 실행 취소 / 다시 실행은 해당 메모리 만 실행 취소 / 다시 실행합니다. 개체 내부에서 부분 실행 취소 / 다시 실행을 수행해야하는 경우 상황이 더욱 흥미로워집니다. 이러한 경우 "방문자 패턴"이라는 새로운 아이디어가 사용됩니다. "개체 수준 실행 취소 / 다시 실행"이라고합니다. 또는 삭제 된 변수 또는 수정 된 변수에는 플래그가 주어 지므로 실행 취소 / 다시 실행은 해당 메모리 만 실행 취소 / 다시 실행합니다. 개체 내부에서 부분 실행 취소 / 다시 실행을 수행해야하는 경우 상황이 더욱 흥미로워집니다. 이러한 경우 "방문자 패턴"이라는 새로운 아이디어가 사용됩니다. "개체 수준 실행 취소 / 다시 실행"이라고합니다.
- 개체 수준 실행 취소 / 다시 실행 : 실행 취소 / 다시 실행 알림이 호출되면 모든 개체는 스트리밍 작업을 구현합니다. 여기서 스 트리머는 개체에서 프로그래밍 된 이전 데이터 / 새 데이터를 가져옵니다. 방해받지 않는 데이터는 방해받지 않습니다. 모든 개체는 스 트리머를 인수로 가져오고 UNDo / Redo 호출 내에서 개체의 데이터를 스트리밍 / 언 스트림합니다.
1과 2 모두 1. BeforeUndo () 2. AfterUndo () 3. BeforeRedo () 4. AfterRedo ()와 같은 메서드를 가질 수 있습니다. 이러한 메서드는 모든 개체가 특정 작업을 얻기 위해 이러한 메서드도 구현하도록 기본 실행 취소 / 다시 실행 명령 (컨텍스트 명령이 아님)에 게시되어야합니다.
좋은 전략은 1과 2의 하이브리드를 만드는 것입니다. 장점은 이러한 방법 (1 & 2) 자체가 명령 패턴을 사용한다는 것입니다.