CAN SOMEBODY EXPLAIN HOW A MEMENTO DESIGN PATTERN REALLY WORKS?

Hi there, I'm struggling to understand the concept of a memento design pattern, can somebody explain to me in the form of code. And please give real life situations where one would need a memento implementated program. Thanks
The most common real life uses of the memento pattern is in supporting undo operations (as in an graphic editor) / rollback of transactions.

A trivial example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <memory>

////////  header ////////////

struct rectangle
{
    void move_to( int x, int y ) ;
    void metamorphose() ;
    void resize_to_optimum() ;
    void draw() const ;

    struct memento ; // externalized state (without violating encapsulation)
    std::shared_ptr<memento> curr_state() const ;
    void restore_state( std::shared_ptr<memento> ) ;

    rectangle() ;

    struct implementation ;
    private:
        std::unique_ptr<implementation> opaque ;
};

////////  implementation ////////////

#include <iostream>
#include <algorithm>

struct rectangle::implementation
{
    int x = 0 ;
    int y = 0 ;
    int w = 10 ;
    int h = 10 ;

    void move_to( int _x, int _y ) { x = _x ; y = _y ; }

    void metamorphose() { ++x ; --y ; ++w ; --h ; }

    void resize_to_optimum() { w += std::max( h, 5 ) ; }

    void draw()
    {
        std::cout << "rectangle { (" << x << ',' << y << "), "
                   << w << 'X' << h << " }\n" ;
    }
};

struct rectangle::memento
{
    memento( const rectangle::implementation& s ) : state(s) {}
    const rectangle::implementation state ;
};

std::shared_ptr<rectangle::memento> rectangle::curr_state() const
{ return std::make_shared<memento>( *opaque ) ; }

void rectangle::restore_state( std::shared_ptr<rectangle::memento> p )
{ if(p) *opaque = p->state ; }

rectangle::rectangle() : opaque( new implementation ) {}
void rectangle::move_to( int x, int y ) { opaque->move_to(x,y) ; }
void rectangle::metamorphose() { opaque->metamorphose() ; }
void rectangle::resize_to_optimum() { opaque->resize_to_optimum() ; }
void rectangle::draw() const { opaque->draw() ; }

////////  client ////////////

int main()
{
    rectangle r ;
    r.draw() ;
    auto old_state = r.curr_state() ;

    r.move_to( 99, 765 ) ;
    r.metamorphose() ;
    r.resize_to_optimum() ;
    r.draw() ;

    r.restore_state(old_state) ;
    r.draw() ;
}


http://liveworkspace.org/code/1TR2zv$0

As an aside: please do not shout.

Last edited on
Thank you very much JLborges, now I understand it.
Topic archived. No new replies allowed.