Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 163cd63

Browse filesBrowse files
committed
add memento pattern
1 parent 85bb057 commit 163cd63
Copy full SHA for 163cd63

File tree

Expand file treeCollapse file tree

8 files changed

+342
-3
lines changed
Filter options
Expand file treeCollapse file tree

8 files changed

+342
-3
lines changed

‎BehavioralPatterns/BehavioralPatterns.csproj

Copy file name to clipboardExpand all lines: BehavioralPatterns/BehavioralPatterns.csproj
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
<Compile Include="Mediator\ParticipantColleague.cs" />
4747
<Compile Include="Mediator\ChatRoomMediator.cs" />
4848
<Compile Include="Mediator\TestMediator.cs" />
49+
<Compile Include="Memento\Caretaker.cs" />
50+
<Compile Include="Memento\Memento.cs" />
51+
<Compile Include="Memento\Originator.cs" />
4952
<Compile Include="NullObject\ConsoleLog.cs" />
5053
<Compile Include="NullObject\ILog.cs" />
5154
<Compile Include="NullObject\NullLog.cs" />
@@ -70,6 +73,7 @@
7073
<None Include="doc\Strategy.cd" />
7174
<None Include="doc\TemplateMethod.cd" />
7275
<None Include="Mediator\README.md" />
76+
<None Include="Memento\README.md" />
7377
<None Include="NullObject\README.md" />
7478
<None Include="Observer\README.md" />
7579
<None Include="Strategy\README.md" />
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace BehavioralPatterns.Memento
8+
{
9+
public class Caretaker
10+
{
11+
public static void Run()
12+
{
13+
IList<Memento> mementoes = new List<Memento>();
14+
15+
Originator originator = new Originator();
16+
originator.SetState("State 1");
17+
originator.SetState("State 2");
18+
mementoes.Add(originator.Save()); // checkpoint 1
19+
20+
originator.SetState("State 3");
21+
mementoes.Add(originator.Save()); // checkpoint 2
22+
23+
originator.SetState("State 4");
24+
originator.Restore(mementoes[0]); // restore to checkpoint 1
25+
}
26+
}
27+
}

‎BehavioralPatterns/Memento/Memento.cs

Copy file name to clipboard
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace BehavioralPatterns.Memento
8+
{
9+
[Serializable]
10+
class Memento
11+
{
12+
public string State { get; }
13+
14+
public Memento(String state)
15+
{
16+
this.State = state;
17+
}
18+
}
19+
}
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace BehavioralPatterns.Memento
8+
{
9+
class Originator
10+
{
11+
private String _state;
12+
13+
public void SetState(String state)
14+
{
15+
this._state = state;
16+
Console.WriteLine($"State is set to {state}");
17+
}
18+
19+
public Memento Save()
20+
{
21+
Console.WriteLine($"Saving state to Memento");
22+
return new Memento(this._state);
23+
}
24+
25+
public void Restore(Memento m)
26+
{
27+
this._state = m.State;
28+
Console.WriteLine($"State is restored from Memento: {_state}");
29+
}
30+
}
31+
}

‎BehavioralPatterns/Memento/README.md

Copy file name to clipboard
+139Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Momento
2+
3+
Use the Mediator Pattern to centralize complex communications and control between related objects.
4+
5+
## Problem
6+
7+
* Tight coupling between a set of interacting objects should be avoided.
8+
* It should be possible to change the interaction between a set of objects independently.
9+
10+
*Tightly coupled objects* are hard to implement, change, test and reuse.
11+
12+
## Solution
13+
14+
* Define a `Mediator` object that encapsulates the interaction between a set of objects.
15+
* Objects delegate their interaction to a mediator object instead of interacting with each other directly.
16+
17+
This makes the objects *loosely coupled*.
18+
19+
The Mediator is commonly used to coordinate related GUI components.
20+
21+
## Benefits
22+
23+
* Colleagues classes may become more reusable and are decoupled from the system.
24+
* Simplifies maintenance of the system by centralizing control logic.
25+
* Simplifies and reduces the variety of messages sent between objects in the system.
26+
27+
## Drawbacks
28+
29+
* Without proper design, the mediator object can become overly complex.
30+
* Single point of failure
31+
* Hard to test --> Objects should be mocked
32+
33+
## Common Structure
34+
35+
![Common structure of mediator pattern](https://upload.wikimedia.org/wikipedia/commons/9/92/W3sDesign_Mediator_Design_Pattern_UML.jpg)
36+
37+
* Mediator (IChatRoom)
38+
* defines an interface for communicating with Colleague objects
39+
* ConcreteMediator (ChatRoom)
40+
* implements cooperative behavior by coordinating Colleague objects.
41+
* knows and maintains its colleagues.
42+
* Colleague (IParticipant)
43+
* defines an interface for using Colleague objects.
44+
* ConcreateColleague (Participant)
45+
* each colleague knows its Mediator object
46+
* each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague.
47+
48+
_[Source: http://www.dofactory.com/net/mediator-design-pattern]_
49+
50+
## Example
51+
52+
![Mediator Pattern](/Diagrams/Mediator.png)
53+
54+
Mediator
55+
```cs
56+
public interface IChatRoom
57+
{
58+
void RegisterParticipant(IParticipant participant);
59+
void Send(String from, String to, string message);
60+
}
61+
```
62+
63+
ConcreteMediator
64+
```cs
65+
public class ChatRoom : IChatRoom
66+
{
67+
private readonly IDictionary<string, IParticipant> _participants = new Dictionary<string, IParticipant>();
68+
69+
public void RegisterParticipant(IParticipant participant)
70+
{
71+
this._participants.Add(participant.GetName(), participant);
72+
}
73+
74+
public void Send(string from, string to, string message)
75+
{
76+
if (this._participants.ContainsKey(to))
77+
{
78+
this._participants[to].Receive(from, message);
79+
}
80+
else
81+
{
82+
throw new ArgumentException("{0} not found", to);
83+
}
84+
}
85+
}
86+
```
87+
88+
Colleague
89+
```cs
90+
public interface IParticipant
91+
{
92+
string GetName();
93+
void Send(string to, string message);
94+
void Receive(string from, string message);
95+
}
96+
```
97+
98+
ConcreteColleague
99+
```cs
100+
public class Participant : IParticipant
101+
{
102+
private readonly string _name;
103+
private readonly IChatRoom _chatRoom;
104+
105+
public Participant(string name, IChatRoom chatRoom)
106+
{
107+
this._name = name;
108+
this._chatRoom = chatRoom;
109+
110+
this._chatRoom.RegisterParticipant(this);
111+
}
112+
public string GetName()
113+
{
114+
return this._name;
115+
}
116+
117+
public void Send(string to, string message)
118+
{
119+
this._chatRoom.Send(this._name, to, message);
120+
}
121+
122+
public void Receive(string from, string message)
123+
{
124+
Console.WriteLine("{0} to {1}: {2}", from, this._name, message);
125+
}
126+
}
127+
```
128+
129+
Usage
130+
```cs
131+
IChatRoom chatRoom = new ChatRoom();
132+
133+
IParticipant einstein = new Participant("Einstein", chatRoom);
134+
IParticipant newton = new Participant("Newton", chatRoom);
135+
IParticipant galileo = new Participant("Galileo", chatRoom);
136+
137+
newton.Send(galileo.GetName(), "I discoverd laws of motion");
138+
einstein.Send(newton.GetName(), "I discovered how gravity works");
139+
```

‎BehavioralPatterns/Momento/README.md

Copy file name to clipboard
+116Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Memento
2+
3+
The Memento pattern provides the abilitiy to restore an object to its previous state later.
4+
5+
## Problem
6+
7+
* The internal state of an object should be saved externally so that the object can be restored to this state later.
8+
* The object's encapsulation must not be violated.
9+
10+
## Solution
11+
12+
Make an object (originator) itself responsible for
13+
* saving its internal state to a `memento` object and
14+
* restoring to a previous state from a `memento` object.
15+
16+
Only the originator that created a memento is allowed to access it.
17+
18+
A client (caretaker) can request a memento from the originator to save the internal state. It can also pass a memento back to the originator to restore to a previous state.
19+
20+
## Benefits
21+
22+
* Does not violate the originator's encapsulation.
23+
* Keeping the saved state external from the originator helps to maintain cohesion.
24+
* Provides easy-to-implement recovery capability.
25+
26+
## Drawbacks
27+
28+
* Saving and restoring state can be time consuming.
29+
* It may require lots of memory if clients create mementors too often.
30+
* Clients should track the originator's lifecycle in order to destroy obsolete mementos.
31+
32+
## Common Structure
33+
34+
![Common structure of memento pattern](https://upload.wikimedia.org/wikipedia/commons/3/38/W3sDesign_Memento_Design_Pattern_UML.jpg)
35+
36+
* Memento
37+
* is a value object that stores internal state of the Originator object.
38+
* It is common practice to make Memento immutable and pass it data only once, via constructor.
39+
* Originator
40+
* creates a memento containing a snapshot of its current internal state.
41+
* uses the memento to restore its internal state
42+
* Caretaker
43+
* keeps a history of originator's state by storing a stack of mementos
44+
* never operates on or examines the contents of a memento
45+
* When originator has to go back in history, the caretaker passes the last memento to the originator's restoration method.
46+
47+
_[Source: http://www.dofactory.com/net/memento-design-pattern]_
48+
49+
## Example
50+
51+
Memento
52+
```cs
53+
[Serializable]
54+
class Memento
55+
{
56+
public string State { get; }
57+
58+
public Memento(String state)
59+
{
60+
this.State = state;
61+
}
62+
}
63+
```
64+
65+
Originator
66+
```cs
67+
class Originator
68+
{
69+
private String _state;
70+
71+
public void SetState(String state)
72+
{
73+
this._state = state;
74+
Console.WriteLine($"State is set to {state}");
75+
}
76+
77+
public Memento Save()
78+
{
79+
Console.WriteLine($"Saving state to Memento");
80+
return new Memento(this._state);
81+
}
82+
83+
public void Restore(Memento m)
84+
{
85+
this._state = m.State;
86+
Console.WriteLine($"State is restored from Memento: {_state}");
87+
}
88+
}
89+
```
90+
91+
CareTaker
92+
```cs
93+
IList<Memento> mementoes = new List<Memento>();
94+
95+
Originator originator = new Originator();
96+
originator.SetState("State 1");
97+
originator.SetState("State 2");
98+
mementoes.Add(originator.Save()); // checkpoint 1
99+
100+
originator.SetState("State 3");
101+
mementoes.Add(originator.Save()); // checkpoint 2
102+
103+
originator.SetState("State 4");
104+
originator.Restore(mementoes[0]); // restore to checkpoint 1
105+
```
106+
107+
Output
108+
```
109+
State is set to State 1
110+
State is set to State 2
111+
Saving state to Memento
112+
State is set to State 3
113+
Saving state to Memento
114+
State is set to State 4
115+
State is restored from Memento: State 2
116+
```

‎BehavioralPatterns/Program.cs

Copy file name to clipboardExpand all lines: BehavioralPatterns/Program.cs
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
using System.Text;
55
using System.Threading.Tasks;
66
using BehavioralPatterns.Mediator;
7+
using BehavioralPatterns.Memento;
78

89
namespace BehavioralPatterns
910
{
1011
class Program
1112
{
1213
static void Main(string[] args)
1314
{
14-
TestMediator.Run();
15+
Caretaker.Run();
16+
Console.ReadKey();
1517
}
1618
}
1719
}

‎README.md

Copy file name to clipboardExpand all lines: README.md
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Design Patterns in C# / .NET
44
[![Build Status](https://travis-ci.org/tk-codes/DesignPatterns.NET.svg?branch=master)](https://travis-ci.org/tk-codes/DesignPatterns.NET)
55
![Language C#](https://img.shields.io/badge/language-c%23-blue.svg)
66
![status in progress](https://img.shields.io/badge/status-in%20progress-brightgreen.svg)
7-
![number of patterns](https://img.shields.io/badge/patterns-13-red.svg)
7+
![number of patterns](https://img.shields.io/badge/patterns-14-red.svg)
88

99
## Creational Patterns
1010

@@ -38,7 +38,7 @@ Design Patterns in C# / .NET
3838
| | Interpreter
3939
| | Iterator
4040
|:heavy_check_mark: | [Mediator](/BehavioralPatterns/Mediator)|
41-
| | Memento
41+
|:heavy_check_mark:| [Memento](/BehavioralPatterns/Memento)|
4242
| :heavy_check_mark: | [Null Object](/BehavioralPatterns/NullObject) |
4343
| :heavy_check_mark:| [Observer](/BehavioralPatterns/Observer/) |
4444
| | State | :warning:
@@ -51,3 +51,4 @@ Design Patterns in C# / .NET
5151
* MSDN - [Patterns & Practices](https://msdn.microsoft.com/en-us/library/ff921345.aspx)
5252
* dotFactory - http://www.dofactory.com/net/design-patterns
5353
* Wikipedia - https://en.wikipedia.org/wiki/Software_design_pattern
54+
* Refactoring.Guru - https://refactoring.guru/design-patterns

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.