100 lines of code, easy to handle the draft box in the text editor

Keywords: Java Design Pattern architecture

This article is excerpted from "design patterns should be learned this way"

1 use memo mode to realize the draft box function

We have all used the rich text editor in web pages. The editor usually comes with operations such as draft box and undo. The following code is used to realize such a function. Suppose we publish an article in the GPer community. The process of editing the article takes a long time, and it will be constantly revoked and modified. It may even take several days to write a boutique article. Therefore, the edited content may be saved to the draft box in real time.
First create the initiator role Editor class.

public class Editor {

    private String title;
    private String content;
    private String imgs;

    public Editor(String title, String content, String imgs) {
        this.title = title;
        this.content = content;
        this.imgs = imgs;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getImgs() {
        return imgs;
    }

    public void setImgs(String imgs) {
        this.imgs = imgs;
    }

    public ArticleMemento saveToMemento() {
        ArticleMemento articleMemento = new ArticleMemento(this.title,this.content,this.imgs);
        return articleMemento;
    }

    public void undoFromMemento(ArticleMemento articleMemento) {

        this.title = articleMemento.getTitle();
        this.content = articleMemento.getContent();
        this.imgs = articleMemento.getImgs();
    }

    @Override
    public String toString() {
        return "Editor{" +
                "title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", imgs='" + imgs + '\'' +
                '}';
    }
}

Then create the memo role ArticleMemento class.

public class ArticleMemento {
    private String title;
    private String content;
    private String imgs;

    public ArticleMemento(String title, String content, String imgs) {
        this.title = title;
        this.content = content;
        this.imgs = imgs;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }

    public String getImgs() {
        return imgs;
    }

    @Override
    public String toString() {
        return "ArticleMemento{" +
                "title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", imgs='" + imgs + '\'' +
                '}';
    }
}

Then create the memo management role draft box DraftsBox class.

public class DraftsBox {

    private final Stack<ArticleMemento> STACK = new Stack<ArticleMemento>();

    public ArticleMemento getMemento() {
        ArticleMemento articleMemento= STACK.pop();
        return articleMemento;
    }

    public void addMemento(ArticleMemento articleMemento) {
        STACK.push(articleMemento);
    }

}

The Stack class defined in the draft box is a subclass of Vector, which implements a standard last in first out Stack. As shown in the following table, the following methods are mainly defined.

Method definitionMethod description
boolean empty()Test whether the stack is empty
Object peek( )View the object at the top of the stack, but do not remove it from the stack
Object pop( )Removes the object at the top of the stack and returns it as the value of this function
Object push(Object element)Push the object to the top of the stack
int search(Object element)Returns the position of the object in the stack, based on 1

Finally, write the client test code.

    public static void main(String[] args) {
        DraftsBox draftsBox = new DraftsBox();

        Editor editor = new Editor("I write like this Spring Yes, although sparrows are small, they have all five internal organs",
                "This article is excerpted from< Spring5 Core principles and 30 classes, Tom Published by electronic industry press.",
                "35576a9ef6fc407aa088eb8280fb1d9d.png");

        ArticleMemento articleMemento = editor.saveToMemento();
        draftsBox.addMemento(articleMemento);

        System.out.println("title:" + editor.getTitle() + "\n" +
                            "Content:" + editor.getContent() + "\n" +
                            "Illustration:" + editor.getImgs() + "\n Staging succeeded");

        System.out.println("Complete information" + editor);


        System.out.println("==========Modify the article for the first time===========");
        editor.setTitle("[Tom I wrote it this way Spring Yes, although sparrows are small, they have all five internal organs");
        editor.setContent("This article is excerpted from< Spring5 Core principles and 30 classes, Tom Write");

        System.out.println("==========The first revision of the article is completed===========");

        System.out.println("Complete information" + editor);

        articleMemento = editor.saveToMemento();

        draftsBox.addMemento(articleMemento);

        System.out.println("==========Save to draft===========");


        System.out.println("==========The second revision of the article===========");
        editor.setTitle("Handwritten Spring");
        editor.setContent("This article is excerpted from< Spring5 Core principles and 30 classes, Tom Write");
        System.out.println("Complete information" + editor);
        System.out.println("==========The second revision of the article is completed===========");

        System.out.println("==========1st cancellation===========");
        articleMemento = draftsBox.getMemento();
        editor.undoFromMemento(articleMemento);
        System.out.println("Complete information" + editor);
        System.out.println("==========Completion of the first cancellation===========");


        System.out.println("==========Second cancellation===========");
        articleMemento = draftsBox.getMemento();
        editor.undoFromMemento(articleMemento);
        System.out.println("Complete information" + editor);
        System.out.println("==========The second cancellation is completed===========");

}

The operation results are shown in the figure below.

2. Application of memo pattern in Spring source code

Memo mode is rarely used in the framework source code, mainly in combination with specific application scenarios. The author looked in the JDK source code. So far, no specific application has been found, including the corresponding source code in MyBatis. A StateManageableMessageContext interface is found in the Webflow source code of Spring. The source code is as follows.

public interface StateManageableMessageContext extends MessageContext {


    public Serializable createMessagesMemento();

    
    public void restoreMessages(Serializable messagesMemento);

    
    public void setMessageSource(MessageSource messageSource);
}

We see that there is a createMessagesMemento() method to create a message memo. You can open its implementation class. The code is as follows.

public class DefaultMessageContext implements StateManageableMessageContext {

    private static final Log logger = LogFactory.getLog(DefaultMessageContext.class);

    private MessageSource messageSource;

    @SuppressWarnings("serial")
    private Map<Object, List<Message>> sourceMessages = 
new AbstractCachingMapDecorator<Object, List<Message>>(
                            new LinkedHashMap<Object, List<Message>>()) {

        protected List<Message> create(Object source) {
            return new ArrayList<Message>();
        }
    };

    ...

    public void clearMessages() {
        sourceMessages.clear();
    }

    // implementing state manageable message context

    public Serializable createMessagesMemento() {
        return new LinkedHashMap<Object, List<Message>>(sourceMessages);
    }

    @SuppressWarnings("unchecked")
    public void restoreMessages(Serializable messagesMemento) {
        sourceMessages.putAll((Map<Object, List<Message>>) messagesMemento);
    }

    public void setMessageSource(MessageSource messageSource) {
        if (messageSource == null) {
            messageSource = new DefaultTextFallbackMessageSource();
        }
        this.messageSource = messageSource;
    }

    ...

}

We see that its main logic is equivalent to leaving a backup for Message for recovery.

Focus on WeChat's official account of Tom architecture and reply to the "design pattern" to get the complete source code.

[recommendation] Tom bomb architecture: 30 real cases of design patterns (with source code attached). Challenging the annual salary of 60W is not a dream

This article is the original of "Tom bomb architecture". Please indicate the source for reprint. Technology lies in sharing, I share my happiness!
If this article is helpful to you, you are welcome to pay attention and praise; If you have any suggestions, you can also leave comments or private letters. Your support is the driving force for me to adhere to my creation. Focus on WeChat official account Tom structure, get more dry cargo!

Posted by discobean on Mon, 22 Nov 2021 23:37:01 -0800