[JAVA] Try design patterns in C language! Memento pattern-Let's memorize the memories of the data

** Introduction **

"Try in C! Design pattern" This time is the Memento pattern. In a word, it's a DB rollback. If you think about it carefully, I think it's a useful pattern.

List of design patterns Description of the created library package The public code is here

** Memento pattern **

The explanation of wikipedia is as follows.

The memento pattern (English: Memento pattern, Japan: Memento pattern) is one of the software design patterns that provides the ability to return an object to its previous state (by rollback).

It's simple. Even if you look at Techscore's explanation and the class diagram below, Originator has a mechanism to return to the original state using the Mememt class that holds the state.

画像

Looking back on the past, I wondered what it was used for. There were quite a few use cases that seemed useful.

** Usage **

** Data rollback **

If you are using DB, you can use the rollback function, but if you have a system with a simple data storage mechanism, you do not need to use DB, so if you want to restore it in case of an error, an error will occur. Sometimes I see it implemented in a squeaky code.

I thought it would be unavoidable if I didn't need to use the DB, but I often feel motivated to "remember the previous state".

** State transition **

Especially when developing the screen, press the "Back" button to return to the original screen state. Rollback processing like this is necessary in various ways. Enable this previous View and this View so that this button can be used.

When I developed an Android application as a hobby before, what is the smart way to do this? I was developing while worrying about it all the time. At that time

--A class dedicated to screen state management transition is set up, and when the screen is transitioned, the transition is returned as "Next is what state" and "back is what state".

I was doing something like that. Change the View layout while being aware of the previous state. Like this I feel like I've done my best as an amateur, but I'm sure I'll die because of the large amount of changes to the screen changes.

** If you don't use Memento **

Button event management class


//Event management class for each button
public class ActivityListenerPresenter {
    public static ActivityListenerPresenterImple mInstance;

    public static ActivityListenerPresenterImple getInstance() {
        if(mInstance == null) mInstance = new ActivityListenerPresenterImple();
        return mInstance;
    }

    //Perform screen transition for each button event
...
    //Pushed back
    public static boolean goBack() {
        return getInstance().goBack();
    }
}

Button event management class(This mounting side


public class ActivityListenerPresenterImple {
...
   public boolean goBack() {
        //Status acquisition
        ActivityListenerState prevState = mActivityStateAction.getPrev();
        Log.v(TAG_LOG, "Prev state=" + prevState);
        goNext(prevState);
        return true;
    }

    private void goNext(ActivityListenerState state) {
        //Status acquisition
        mActivityStateAction = getActivityStateAction(state);
        //Display the screen according to the state
        mActivityStateAction.showCurrent();
    }

    private ActivityStateAction getActivityStateAction(ActivityListenerState state) {
        Log.v(TAG_LOG, "getActivityStateAction=" + state);
        ActivityStateAction action=null;
        switch(state) {
            case MYVIDEO_LIST:
                action = new ActivityStateActionMYVIDEO_LIST();
                break;
            case MYVIDEO_RUN:
                action = new ActivityStateActionMYVIDEO_RUN();
                break;
            ...
        }
        return action;
    }

    //I will do my best to implement what the prev will be in each state
    private interface ActivityStateAction{
        //Actual view switching
        public void showCurrent();
        //Do your best to return to prev
        public ActivityListenerState getPrev();
    }

For example, using the idea of mement, it may have been possible to memorize the previous state at the time of state transition and restore it even without getPrev. It won't be simple like this, but this one seems to have better code volume and readability.

** Expectations when using Memento **

Button event management class(This mounting side


public class ActivityListenerPresenterImple {
...
   public boolean goBack() {
        //Status acquisition
        mActivityStateAction = setMementPrevActivityStateAction()
        //Display the screen according to the state
        mActivityStateAction.showCurrent();
        return true;
    }

    private void goNext(ActivityListenerState state) {
        //Keep the previous state
        mementPrevActivityStateAction(mActivityStateAction);
        //Status acquisition
        mActivityStateAction = getActivityStateAction(state);
        //Display the screen according to the state
        mActivityStateAction.showCurrent();
    }

///getActivityStateAction remains unchanged

    //Isn't the interface of each state only good with showCurrent?
    private interface ActivityStateAction{
        //Actual view switching
        public void showCurrent();
        //public ActivityListenerState getPrev();
    }

Library

When I recall various things, I tried to make a library of memento and use cases where I can see the scenes I want. The contents I am doing are almost the same as at the time of prototype.

Overview

--Record memories (instance information) in the library. ――Be able to dig up the memories you remember.

Basically, rollback at the time of error is assumed.

** Class design **

This time it is supposed to be disposable every time, so there is no class design. So omitted.

good point

――It's easy not to remember what kind of state you should return to

** Bad points **

--After all, the process of digging up memories is left to the implementation user

Operating environment

Confirmed on Ubuntu 18.04 Desktop, CentOS 7.5.1804. I think it works on Linux.

** Details **

** API definition **

mement.h


/*Mement Register definition*/
struct mement_register_t;
typedef struct mement_register_t *MementRegister;

/*User-implemented function definition. The default is memcpy and free do nothing(Body instance destroyed with Mement Register*/
struct mement_method_t {
        /*Since the instance of mement is in the library, its constructor*/
        void (*constructor) (void *instance, void * base, size_t base_length);

        /*copy of memento*/
        void (*copy) (void *broken_instance, void * base, size_t base_length);

        /*Release of memento. The base entity is acquired together with Mement Register, so it is not freed.*/
        void (*free) (void * base, size_t base_length);
};

typedef struct mement_method_t mement_method_t;

/*mement registration*/
MementRegister mement_register(void * base, size_t base_length, mement_method_t                                                                                                                                                                              * method);
/*unregister memento*/
void mement_unregister(MementRegister this);
/*Memento memories*/
void mement_remember(MementRegister this, void * broken_instance, int is_unregister_mement);

** How to use: **

  1. Register memories with mement_register
  2. Remember with mement_remember. If is_unregister_mement is non-zero, forget about it at that point.
  3. Use mement_unregister to forget the memories you didn't forget with mement_remember.

code

It is located below. https://github.com/developer-kikikaikai/design_pattern_for_c/tree/master/mement

You don't need a sample, right? Just remember the data you held. Please refer to the code of mement / test if necessary.

Finally

Record your memories so that you can remember them. I think it's a simple but excellent idea. I made a mistake in the git operation of memento and deleted the whole code including the test.

It's important to keep a record

reference

18. Memento pattern

Recommended Posts

Try design patterns in C language! Memento pattern-Let's memorize the memories of the data
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 10)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 7)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 3)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 9)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 6)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 4)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 5)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 2)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 1)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 11)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 12)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 8)
[Order method] Set the order of data in Rails
Java language from the perspective of Kotlin and C #
The story of throwing BLOB data from EXCEL in DBUnit
Let's rewrite the C language assignment of the university with Node.js