The memento pattern

The memento pattern is a state management technique that you can use to restore your work to a previous state when needed. A common example is the Undo function of a word processor application. After making 10 changes, we can always undo the prior operations and return to the original state before those 10 changes were made. Similarly, an application may remember the most recently opened files and provide a menu of choices so that the user can quickly reopen a previously opened file.

Implementing the memento pattern in Julia is quite simple. We can just store previous states in an array and when making a change, we can push the new state to the array. When we want to undo our actions, we restore the previous state by popping from the array. To illustrate this idea, let's consider the case of a blog post-editing application. We can define the data types as follows:

struct Post
title::String
content::String
end

struct Blog
author::String
posts::Vector{Post}
date_created::DateTime
end

As you can see, a Blog object contains an array of Post objects. By convention, the last element in the array is the current version of the blog post. If there were five posts in the array, then it means that four changes have been made so far. Creating a new blog is as easy, as shown in the following code:

function Blog(author::String, post::Post)
return Blog(author, [post], now())
end

By default, a new blog object contains just one version. As the user makes changes, the array will grow. For convenience, we can provide a version_count function that returns the number of revisions that the user has made so far.

version_count(blog::Blog) = length(blog.posts)

To obtain the current post, we can simply take the last element of the array:

current_post(blog::Blog) = blog.posts[end]

Now, when we have to update the blog, we must push the new version to the array. Here is the function that we use to update the blog with a new title or content:

function update!(blog::Blog; 
title = nothing,
content = nothing)
post = current_post(blog)
new_post = Post(
something(title, post.title),
something(content, post.content)
)
push!(blog.posts, new_post)
return new_post
end

The update! function takes a Blog object, and optionally it can take either an updated title, content, or both. Basically, it creates a new Post object and pushes it into the posts array. Undoing is done as follows:

function undo!(blog::Blog)
if version_count(blog) > 1
pop!(blog.posts)
return current_post(blog)
else
error("Cannot undo... no more previous history.")
end
end

We can test it with the following test function:

function test()
blog = Blog("Tom", Post("Why is Julia so great?", "Blah blah."))
update!(blog, content = "The reasons are...")

println("Number of versions: ", version_count(blog))
println("Current post")
println(current_post(blog))

println("Undo #1")
undo!(blog)
println(current_post(blog))

println("Undo #2") # expect failure
undo!(blog)
println(current_post(blog))
end

The output is shown as follows:

As you can see, it is quite easy to implement the memento pattern. We will cover the observer pattern next.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.83.96