본문 바로가기
컴퓨터 과학/디자인패턴

[디자인패턴] 행위 패턴(6) : 메멘토(Memento)

by webcodur 2024. 3. 25.
728x90
반응형

목차

     

     

    메멘토(Memento)

    메멘토 디자인 패턴은 객체의 상태를 특정 시점에 캡처하여 나중에 해당 상태로 객체를 복원할 수 있도록 하는 디자인 패턴이다. 이 패턴의 명칭은 '기억을 보존하는 것'을 의미하는 라틴어 'Memento'에서 유래했다. 이 패턴은 주로 되돌리기 기능이나 스냅샷, 상태 복원 기능이 필요할 때 유용하게 사용된다.

    메멘토 패턴은 크게 세 가지 기본 구성요소로 이루어져 있다:

    1. Originator(발생자): 자신의 상태를 저장하거나 복원할 수 있는 객체.
    2. Memento(메멘토): 발생자의 상태를 저장하는 객체. 발생자 외에는 이 객체에 접근할 수 없어야 한다.
    3. Caretaker(케어테이커): 메멘토를 저장하는 객체. 메멘토의 내용을 조작하거나 직접 접근하지 않고, 메멘토를 관리(저장하거나 복원 요청)하는 역할만 수행한다.

     

    패턴 미적용 예시

    간단한 게임에서 플레이어의 상태(예: 위치, 체력 등)를 저장하고 복원하는 기능을 구현하지 않고, 게임 상태를 직접 조작하는 예시를 생각해볼 수 있다. 이 경우, 게임의 복잡성이 증가할수록 상태 관리의 어려움이 커지고, 상태 복원이나 되돌리기 기능 구현이 어려워진다.

    class Player
    {
        public int Health { get; set; }
        public string Position { get; set; }
    
        // 플레이어 상태 변경
        public void TakeDamage(int damage)
        {
            Health -= damage;
        }
    
        // 플레이어 위치 변경
        public void MoveTo(string newPosition)
        {
            Position = newPosition;
        }
    }
    
    class Game
    {
        public void ProcessGame()
        {
            Player player = new Player() { Health = 100, Position = "Start" };
    
            // 게임 로직 처리
            player.TakeDamage(10); // 플레이어가 데미지를 받음
            player.MoveTo("Forest"); // 플레이어 위치 이동
    
            // 상태 복원 로직이 없어 특정 시점의 상태로 되돌리기 어려움
        }
    }
    
    

    이 코드에서는 Player 객체의 상태(체력, 위치)를 변경하는 메서드가 있지만, 특정 시점의 상태를 저장하거나 복원하는 기능이 구현되어 있지 않다. 이로 인해 발생하는 문제는 다음과 같다:

    • 상태 복원 또는 되돌리기 기능이 필요할 때 추가 구현이 복잡해진다.
    • 상태 관리의 어려움이 증가한다.

     

    메멘토 패턴 적용 예시

    이제 같은 상황에서 메멘토 패턴을 적용하여 플레이어의 상태를 저장하고, 원하는 시점으로 되돌릴 수 있도록 구현한 예시를 살펴보자. 메멘토 패턴을 사용함으로써, 플레이어의 상태 관리를 보다 유연하고 효율적으로 할 수 있다.

     

    메멘토 패턴 구성 요소

    1. Originator(발생자): Player 클래스가 이 역할을 수행하며, 자신의 상태를 저장하고 복원하는 기능을 가진다.
    2. Memento(메멘토): PlayerMemento 클래스는 플레이어 상태의 스냅샷을 저장한다. 이 클래스는 Player 클래스의 상태를 그대로 보관하지만, 외부에서는 접근할 수 없도록 캡슐화한다.
    3. Caretaker(케어테이커): GameCaretaker 클래스가 이 역할을 수행하며, 메멘토 객체를 저장하고 관리한다. 실제 메멘토의 내용은 직접 조작하지 않고, 필요한 시점에 Originator에게 전달하여 상태를 복원한다.
    using System;
    using System.Collections.Generic;
    
    // Originator
    class Player
    {
        public int Health { get; set; }
        public string Position { get; set; }
    
        // 현재 상태를 저장하고 메멘토 객체를 생성한다.
        public PlayerMemento SaveState()
        {
            return new PlayerMemento(Health, Position);
        }
    
        // 메멘토 객체를 받아 상태를 복원한다.
        public void RestoreState(PlayerMemento memento)
        {
            Health = memento.Health;
            Position = memento.Position;
        }
    }
    
    // Memento
    class PlayerMemento
    {
        public int Health { get; private set; }
        public string Position { get; private set; }
    
        public PlayerMemento(int health, string position)
        {
            Health = health;
            Position = position;
        }
    }
    
    // Caretaker
    class GameCaretaker
    {
        private List<PlayerMemento> savedStates = new List<PlayerMemento>();
    
        // 상태를 저장한다.
        public void SaveState(PlayerMemento memento)
        {
            savedStates.Add(memento);
        }
    
        // 지정된 인덱스의 상태를 복원한다.
        public PlayerMemento RestoreState(int index)
        {
            if (index < 0 || index >= savedStates.Count)
                throw new IndexOutOfRangeException("Invalid index");
            return savedStates[index];
        }
    }
    
    class Game
    {
        static void Main(string[] args)
        {
            Player player = new Player() { Health = 100, Position = "Start" };
            GameCaretaker caretaker = new GameCaretaker();
    
            // 초기 상태 저장
            caretaker.SaveState(player.SaveState());
    
            // 게임 로직 처리
            player.TakeDamage(10);
            player.MoveTo("Forest");
    
            // 이전 상태로 복원
            player.RestoreState(caretaker.RestoreState(0));
    
            // 복원된 상태 확인
            Console.WriteLine($"Health: {player.Health}, Position: {player.Position}");
        }
    }
    

     

    이 코드에서 Player 클래스는 자신의 상태(체력, 위치)를 PlayerMemento 객체에 저장하거나, 이 객체로부터 상태를 복원하는 기능을 제공한다. GameCaretaker 클래스는 이러한 PlayerMemento 객체들을 관리하며, 게임의 필요에 따라 특정 시점의 상태를 복원할 수 있도록 한다. 메멘토 패턴을 이용함으로써, 상태의 저장과 복원을 보다 체계적이고 안전하게 관리할 수 있게 된다.

    반응형