Apr 7, 2013 at 11:21am UTC
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
Apr 7, 2013 at 4:55pm UTC
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 Apr 7, 2013 at 4:56pm UTC
Apr 8, 2013 at 7:58am UTC
Thank you very much JLborges, now I understand it.