382. Memento design pattern

Design Pattern נוסף שקיים הוא הDesign Pattern ששמו Memento.

הDesign Pattern בא לפתור את הבעיה הבאה: נניח שיש לנו מחלקה עם State, ואנחנו מעוניינים לשמור את הState הנוכחי כדי שנוכל לשחזר אותו.

למשל, נניח שיש לנו איזשהו אובייקט עם מבנה פנימי ואנחנו מעוניינים לבצע שינוי על המבנה הפנימי ולאחר מכן להתחרט, אבל לא לעשות יותר מדי נזק.

או לחלופין, נניח שיש לנו תהליך מורכב שלוקח זמן ואנחנו מעוניינים לשמור בצד את השלב שאליו הגענו בתהליך עם הפרמטרים של התהליך, כדי שאם האפליקציה שלנו תתרסט נוכל להתחיל את התהליך החל מהנקודה האחרונה אליה הגענו.


תיאור הPattern:

מה שנעשה זה ניצור איזשהו אובייקט שמכיל את הסטטוס שלנו:

נניח שזו מחלקה שמחשבת איזשהי מפה (מספר איטרציות לנקודה במישור):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class IteratedMap
{
private int[,] mPointToIterationNumber;
private int mRowsProcessed;
private int mColumnsProcessed;
private int mRowSize;
private int mColumnSize;
private int mNumberOfIterations;
public void Iterate()
{
// Do some algorithm on mPointToIterationNumber here
}
}

ניצור אובייקט שמכיל את הסטטוס שלה:

1
2
3
4
5
6
public class IteratedMapState
{
public int[,] PointToIterationNumber { get; set; }
public int RowsProcessed { get; set; }
public int ColumnsProcessed { get; set; }
}

בנוסף ניצור שתי פונקציות למחלקה:

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
public class IteratedMap
{
private int[,] mPointToIterationNumber;
private int mRowsProcessed;
private int mColumnsProcessed;
private int mRowSize;
private int mColumnSize;
private int mNumberOfIterations;
// ...
public IteratedMapState SaveState()
{
return new IteratedMapState()
{
PointToIterationNumber = (int[,]) mPointToIterationNumber.Clone(),
ColumnsProcessed = mColumnsProcessed,
RowsProcessed = mRowsProcessed
};
}
public void RecoverState(IteratedMapState state)
{
mPointToIterationNumber = (int[,]) state.PointToIterationNumber.Clone();
mColumnsProcessed = state.ColumnsProcessed;
mRowsProcessed = state.RowsProcessed;
}
}

כך נוכל לשמור ולשחזר את המצב של המחלקה שלנו בשלב כלשהו בתכנית.


נשים לב שעל הState שלנו להיות Deep Clone של הMemberים של האובייקט שלנו, כדי שאם נשנה אותו, נוכל לשחזר את הState הקודם.

בנוסף, נשים לב שמומלץ שSaveState יהיה Thread-safe כדי שהState יהיה אמין במידה ונקרא לו מThread אחר כאשר המחלקה שלנו באמצע תהליך.

לבסוף, כדאי להמנע משימוש בPattern הזה כדי לעשות Undo לנזק שעשינו על מחלקות, מאחר וזה יכול לגרום לקוד שלנו להיות מאוד מסורבל.

המשך יום goto טוב.

שתף