반응형
Notice
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- 파이썬
- 데이터분석
- 보안
- 프로그래밍언어
- 자료구조
- 네트워크보안
- 디자인패턴
- 네트워크
- 컴퓨터공학
- 데이터베이스
- 컴퓨터과학
- springboot
- 소프트웨어공학
- Yes
- 클라우드컴퓨팅
- 알고리즘
- 자바스크립트
- 웹개발
- 버전관리
- 머신러닝
- I'm Sorry
- 사이버보안
- 인공지능
- 프로그래밍
- 데이터과학
- 컴퓨터비전
- 소프트웨어
- 딥러닝
- 데이터구조
- 빅데이터
Archives
- Today
- Total
스택큐힙리스트
커맨드 vs 메멘토: 언제 어떤 패턴이 덜 아픈가 본문
반응형
“되돌리기(Undo)”나 “기록/재실행(Redo·Macro)”가 필요할 때, 팀이 가장 많이 헷갈리는 두 패턴이 커맨드(Command)와 메멘토(Memento)죠. 결론부터 말할게요.
- 작업 자체를 기록·재생하고 싶다면 → 커맨드
- 객체 상태를 ‘그 순간’으로 즉시 되돌리고 싶다면 → 메멘토
두 패턴은 겹치는 영역이 있지만 목표가 다릅니다. 커맨드는 “행위(요청)”를 객체로 만들고 큐잉·지연·원격 실행·로그·매크로까지 다룹니다. 메멘토는 “상태 스냅샷”을 캡슐화해 내부 구현을 노출하지 않고 저장·복원합니다.
언제 커맨드가 맞나?
이럴 때 커맨드가 덜 아픕니다.
- 행위 중심으로 생각해야 할 때: “이 버튼이 누르면 어떤 작업을 수행한다”를 깔끔히 객체화.
- 큐·지연·원격 실행이 필요할 때(잡 큐, 워커, 재시도).
- Audit/로그/매크로가 필요할 때: 기록을 그대로 재생 가능.
- Undo/Redo를 “반대 연산”으로 처리할 수 있을 때(execute()와 unexecute() 쌍).
커맨드는 “요청을 객체로 변환”해서 호출자와 수신자를 느슨하게 분리하고, 실행 취소와 대기열 등을 자연스럽게 지원합니다.
초소형 Kotlin 스케치
interface Command { fun execute(); fun undo() }
class Insert(private val buf: StringBuilder, private val s: String) : Command {
override fun execute() { buf.append(s) }
override fun undo() { buf.delete(buf.length - s.length, buf.length) }
}
언제 메멘토가 맞나?
이럴 때 메멘토가 덜 아픕니다.
- 상태 중심으로 생각해야 할 때: “이전 상태 그대로 복구”가 목표.
- 캡슐화를 지키며 내부 상태를 외부에 노출하고 싶지 않을 때.
- Undo/Redo가 행위의 반대 연산 없이 “스냅샷 복원”만으로 충분할 때(복원 O(1), 심플).
메멘토는 “구현을 드러내지 않고” 객체의 이전 상태를 저장·복원하는 행동 패턴입니다.
초소형 Kotlin 스케치
data class EditorState(val text: String) // Memento
class Editor { var text = ""; fun save() = EditorState(text); fun restore(m: EditorState){ text = m.text } }
비용 구조 한눈에 (감으로 고르는 체크리스트)
- 되돌리기 단위가 ‘행위’인가, ‘상태’인가?
- 행위 단위(매크로, 원격 재생): 커맨드
- 상태 단위(“딱 그 화면 그대로”): 메멘토
- Redo가 ‘다시 실행’이어야 하나? → 커맨드가 유리(재생/대기열/로그).
- 복원이 아주 자주·즉시 일어나나? → 메멘토가 단순(스냅샷 복원).
- 상태가 큰가? 큰 스냅샷을 자주 찍으면 메모리 부담(메멘토)의 대가가 큽니다.
- 반대 연산 정의가 어렵나? 반대 연산이 애매하면 커맨드의 undo()가 지옥이 됩니다 → 메멘토 고려.
- 감사/리플레이가 필수인가?(업무 로그, 매크로) → 커맨드 쪽이 자연스러움.
하이브리드가 정답일 때가 많다
실무에선 둘을 섞는 게 제일 편합니다.
예를 들어, 커맨드로 기록과 재생을 담당하면서 주기적으로 메멘토 체크포인트를 찍어 빠른 복구와 메모리·성능 균형을 잡습니다. 국내 글들도 “둘 중 하나만 고집할 필요 없고 함께 쓰면 좋다”고 정리하죠.
- 패턴: Command 히스토리를 유지하되, N번마다 Memento를 저장
- 복구: 가장 가까운 스냅샷으로 점프 → 남은 커맨드만 재생(콜드 스타트 단축)
- 모바일/안드로이드: 앱 백그라운드 전환 시 메멘토 저장, 전면 복귀 후엔 커맨드 재생으로 세부 동기화
실무 팁 6가지
- Undo/Redo UX 규칙: Undo 후 새로운 편집이 발생하면 Redo 스택은 폐기(편집기 표준). 커맨드든 메멘토든 동일.
- 깊은 복사 주의(메멘토): 참조 공유로 스냅샷이 오염되지 않게 불변 + 딥카피 전략.
- 메모리 관리(메멘토): 스냅샷 압축·델타 저장·기간 제한(예: 30일)로 용량 제어.
- 보상 트랜잭션(커맨드): 외부 API/결제처럼 역함수가 없는 작업은 “보상” 커맨드를 별도 설계.
- 대기열/재시도(커맨드): 실패 시 백오프·리트라이는 Invoker 수준에서 공통 처리.
- 테스트 전략:
- 커맨드: execute()/undo()의 아이템포턴스, 순서 보장 테스트.
- 메멘토: “N번 편집 → 스냅샷 → undo → redo” 경계값(0개/1개/많이) 시나리오.
간단 결론
- 행위 추적·재생·로그가 핵심 → 커맨드
- 상태의 즉시 복원이 핵심 → 메멘토
- 현실은 하이브리드가 제일 덜 아프다(체크포인트 + 커맨드 히스토리).
반응형
'개발' 카테고리의 다른 글
MVC 패턴, 지금까지 가장 많이 쓰인 “기본기”부터 다지자 (2) | 2025.08.09 |
---|---|
Interpreter 패턴: 미니 DSL로 “규칙을 읽는” 코드 만들기 (4) | 2025.08.08 |
메멘토(Memento) 패턴 완전 분석: “되돌리기(Undo)”를 가장 깔끔하게 (2) | 2025.08.08 |
Visitor 패턴: “구조는 그대로, 기능은 덧붙여” (3) | 2025.07.30 |
이어보기 완성! Iterator + Memento로 구현한 플레이백 히스토리 (1) | 2025.07.30 |
Comments