Vi Memo mode

Posted by DontheCat on Thu, 13 Jan 2022 13:13:05 +0100

0. Excerpt from design pattern

  • A memo is an object that stores the state of another object at a certain point in time. The latter is called the originator of the memo.
    Before the state changes, the initiator initializes a memo object according to the current state.
    Only the originator can access the information in the memo.
    The originator can use the information in the memo to restore the state.

  • effect:
    Simplified primary generator
    If the memo is managed by the originator, the encapsulation can be best guaranteed, but this will increase the complexity of the originator, and the customer is required to notify the originator at the end of the work in order to release the saved memo.
    More often, it is left to the customer to manage, but the customer cannot access the internal status of the memo.
    The memo provides a wide interface for the initiator and a narrow interface for the customer - unable to access internal data.

1. Targeted issues

  • When playing games, I usually save a progress before playing the big Boss. If I fail to pass the customs, I can return to the previous progress to restore the original state and start over. Now you need to think about how to implement this scenario in Code:
    The game character has vitality, attack power, defense power and other data. It is different before and after playing Boss. If the player feels that the effect of dueling with Boss is not ideal, he can restore the game to before dueling.

  • One method is to let the role directly save the progress to the class storing the progress. Both classes are the same:

    • GameRole game character class is used to store the data of character's vitality, attack power and defense power.

      class GameRole
      {
          //vitality
          private int vit;
          public int Vitality()
          {
              return vit; 
          }
      
          //aggressivity
          private int atk;
          public int Attack()
          {
              return atk;
          }
      
          //Defensive power
          private int def;
          public int Defense()
          {
              return def; 
          }
      
          //Status display
          public void StateDisplay()
          {
              Console.WriteLine ("Current status of role:");
              Console.WriteLine ("Physical strength:{0}",this.vit);
              Console.WriteLine ("aggressivity:{0}", this.atk);
              Console.WriteLine ("Defense:{0}", this.def); 
          }
      
          //Get initial state
          public void GetlnitState()
          {
              this.vit=100;
              this.atk=100;
              this.def=100;
          }
      
          //State after battle
          public void Fight()
          {
              this.vit=0;
              this.atk=0;
              this.def=0;
          }
      }
      
    • When called by the client:

      static void Main(string[] args)
      {
          //Before the war with Boss 
          GameRole lixiaoyao = new GameRole();
          lixiaoyao.GetlnitState ();
          1ixiaoyao.StateDisplay();
      
          //Save the progress before Boss through a new instance of 'game character'.
          GameRole backup = new GameRole(); 
          backup.Vitality = 1ixiaoyao.Vitality; 
          backup.Attack = 1ixiaoyao.Attack; 
          backup.Defense = 1ixiaoyao.Defense;
      
      
          //When fighting Boss, the loss is serious, and all data loss is zero
          lixiaoyao.Fight ();
          1ixiaoyao.StateDisplay();
      
          //Restore previous state
          lixiaoyao.Vitality = backup.Vitality; 
          lixiaoyao.Attack = backup.Attack; 
          lixiaoyao.Defense = backup.Defense;
      
          lixiaoyao.StateDisplay();
          Console.Read();
      }
      

      The results show that
      Current status of role:
      Physical strength: 100
      Attack power: 100
      Defence: 100
      Current status of role:
      Physical strength: 0
      Attack power: 0
      Defence: 0
      Current status of role:
      Physical strength: 100
      Attack power: 100
      Defence: 100

  • Disadvantages of this implementation:
    If you expose the details of the whole game character to the client, the client's responsibility is too great. You need to know the details of the vitality, attack and defense of the game character; After backup, you need to add new data, such as adding 'magic power' or modifying an existing force, such as changing 'vitality' to 'experience value', which must be modified.

2. Memorandum mode

  • Memo mode: capture the internal state of an object and save the state outside the object without destroying the encapsulation. This will restore the object to its original saved state later.

  • Originator: responsible for creating a memo Memento to record its internal state at the current time, and using the memo to restore the internal state. The originator can decide which internal states Memento stores as needed.

    class Originator
    {
        public String state; 
        
        
        //Create a memo, import the information to be saved and instantiate a memo object
        public Memento CreateMemento()
        {
            return (new Memento(state)); 
        }
        
        //Restore the memo, import the memo and restore the relevant data
        public void SetMemento(Memento memonto)
        {
            state = memento.state;
     
        
        //Display data
        public void Show()
        {
            Console. WriteLine ("State" + state);
        }
    }
    
  • Memo: it is responsible for storing the internal state of the Originator object and preventing other objects other than the Originator from accessing the memo. Memento memos have two interfaces. Caretaker R can see the narrow interface of memos. It can only pass memos to other objects. The Originator can see a wide interface that allows it to access all the data needed to return to the previous state.

    class Memento
    {
        public string state;
        //Construction method to import relevant data
        public Memento (string state) 
        {
            this.state = state;
        }
    
    }
    
  • Caretaker (Manager): responsible for keeping the memo Memento. It cannot operate or check the contents of the memo.
    What we need to save is not all the information, but only some. Therefore, there should be an independent memo class Memento, which only has the properties of the information to be saved.

    class Caretaker
    {
        public Memento memento; 
    }
    
  • Client program

    static void Main(String[] args)
    {
        //Set the initial state of the Originator
        Originator o=new Originator();
        o.state="On";
        o.show();
        
        //When saving, the client cannot see the implementation details of the Originator. The Originator decides what information to save
        Caretaker c=new Caretaker();
        c.memento=o.CreateMemento();
        
        //The Originator changed the status attribute to Off
        o.state="Off";
        o.show;
        
        //Restore the original initial state
        o.SetMemento(c.memento);
        o.show();
        
        Console.Read();
    }
    
  • advantage:

    1. The details to be saved are encapsulated in Memento. Changing the saved details does not affect the client.
    2. Using memos can shield the internal information of complex objects from other objects, so as to properly maintain the boundary of encapsulation.
  • When to use memo mode? (function)

    1. You can use temporarily stored memos to restore the state

    2. Memento mode is applicable to classes with complex functions but need to maintain or record attribute history, or when the attributes to be saved are only a small part of many attributes, the Originator can restore to the previous state according to the saved memento information.

    3. In command mode:

      If you need to implement the command revocation function when using the command mode in a system, the command mode can use the memo mode to store the status of the revocable operation

    4. Sometimes the internal information of some objects must be stored outside the object, but must be read by the object itself. At this time, the memo can shield the complex internal information of the object from other objects, so as to properly maintain the encapsulated boundary.

  • Disadvantages: the role status needs to be completely stored in the memo object. If the status data is very large, the memo object will consume a lot of memory in terms of resource consumption.

Topics: Design Pattern