2014년 7월 11일

Undo / Redo 시스템 디자인

본인이 디자인하는 S/W 기능중 Undo/Redo  적용하기 위해서는 여러가지 방법이 있을 것이다. 그중 모든 행위에 대한 추적을 통해 이력을 관리하는 방법을 설명해 보자.


이러한 디자인의 원칙은 다음과 같다.
undo/redo 가 필요한 모든 행위(함수호출)를 관리하기 위해 하나의 인터페이스를 정의하고 이를 상속 구현하여 연결리스트, 스택등의 자료구조에 차곡차곡 저장해 놓는다.






1. Action 인터페이스

  모든 행위(Action)들은 이 인터페이스를 상속받아 undo / redo 동작을 각각 구현한다. undo 는 반드시 redo 가 한 행위를 반대로 돌려놓아야 한다. 예를 들어 ActionMove 의 경우 어떤 대상을 dx, dy 만큼 이동하는 행위이고 redo 에서 dx, dy 만큼을 더했다면, undo 에서는 dx, dy 만큼을 빼도록 구현한다.

2. Action 인터페이스를 상속받은 실제 액션들 ActionMove, Action,...

 Action 인터페이스를 상속받아 undo/redo 를 구현한다. 유저가 메뉴에서 복사, 붙이기 행위를 한다면 각각 복사(ActionCopy) 객체를 생성하여 ActionControl 의 execute에 전달한다. 이후 붙이기(ActionPaste) 명령을 동일하게 execute 시킨다.
결국 ActionControl.execute() 의 내부에서는 전달받은 Action 인스턴스의 redo 함수를 호출해 주는 것에 불과하다.

3. Action 들을 저장/관리 해주는 컨트롤러 ActionControl

 이 녀석이 실제 생성된 모든 액션(Action,...)들을 자료구조(연결리스트, 스택 등 컨셉에 맞도록 선정)에 지속적으로 쌓아 저장한다. 즉 execute() 호출시 undo 를 시키고 _actions 이라는 컨테이너에 이 인스턴스의 포인터를 쌓아 놓다가, 외부에서 되돌리기 기능이 필요하다면 이 _actions 컨테이너에서 가장 앞단의 Action 인스턴스를 꺼내와 undo 를 호출해 주면 되는 것이다.


위와 같이 액션의 저장과 실제 행위를 분리하여 설계하는 것이 흔한 방식이다.

댓글 1개:

  1. 엄청 오래전에 진행 하셨던 프로젝트네요. 혹시 이런 내용의 프로그램을 만들면서 공부할려면 어떤 교재를 참고해야 하나요 ?
    cok2529@gmail.com 개인 이메일입니다, 시간 되시면 답장 부탁드리겠습니다.

    답글삭제

시리우스 라이브러리 홈페이지 오픈

현재 시리우스(Sirius) 라이브러리라는 제품을 개발하고 이를 소개하는 홈페이지를 오픈 하였습니다. 관심있는 분들의 많은 방문 요청드립니다. 앞으로 업데이트 소식및 변경사항은 스파이럴랩 홈페이지를 통해 진행할 예정입니다. 스파이럴랩 홈페이지 :  h...